slice <- readRDS("Pr_slice_decontX_filtered_annotated_final1.rds")
Warning: cannot open compressed file 'Pr_slice_decontX_filtered_annotated_final1.rds', probable reason 'No such file or directory'Error in gzfile(file, "rb") : cannot open the connection
whole <- readRDS("/Users/nityagupta/Desktop/GM project/best_objects/PrLN_whole_qc_annotated_final.rds")
slice <- readRDS("/Users/nityagupta/Desktop/GM project/best_objects/Pr_slice_decontX0.9_final_newUMAP.rds")
dittoDimPlot(whole, "subcluster_name", do.label = TRUE)
dittoDimPlot(slice, "subcluster_name", do.label = TRUE)
Comparing similar clusters between whole and slices
whole_clusters <- unique(whole$subcluster_name)
whole_result <- data.frame(row.names = rownames(whole))
for (subcluster_name in whole_clusters) {
subset <- whole[, whole$subcluster_name == subcluster_name]
counts <- as.matrix(subset@assays@data@listData[["logcounts"]])
subset_result <- as.data.frame(apply(counts, 1, median))
colnames(subset_result) <- subcluster_name
whole_result <- cbind(whole_result, subset_result)
}
slice_clusters <- unique(slice$subcluster_name)
slice_result <- data.frame(row.names = rownames(slice))
for (subcluster_name in slice_clusters) {
subset <- slice[, slice$subcluster_name == subcluster_name]
counts <- as.matrix(subset@assays@data@listData[["logcounts"]])
subset_result <- as.data.frame(apply(counts, 1, median))
colnames(subset_result) <- subcluster_name
slice_result <- cbind(slice_result, subset_result)
}
Warning: sparse->dense coercion: allocating vector of size 1.5 GiB
slice_colnames <- paste0("s_", colnames(slice_result))
colnames(slice_result) <- slice_colnames
whole_colnames <- paste0("w_", colnames(whole_result))
colnames(whole_result) <- whole_colnames
combined_result <- merge(slice_result, whole_result, by=0)
rownames(combined_result) <- combined_result$Row.names
combined_result$Row.names <- NULL
combined_result$s_gene <- NULL
allfeatures <- modelGeneVar(slice)
allfeatures[order(allfeatures$bio, decreasing=TRUE),]
DataFrame with 21761 rows and 6 columns
mean total tech bio p.value FDR
<numeric> <numeric> <numeric> <numeric> <numeric> <numeric>
CFD 1.94998 5.82566 1.34184 4.48382 3.23325e-121 4.44120e-118
C7 2.13428 4.82406 1.46039 3.36366 9.69493e-59 5.70727e-56
COX2 1.40549 4.36895 1.06228 3.30667 1.72608e-105 1.87180e-102
BMT2 2.75746 3.99958 1.78233 2.21725 1.58857e-18 2.33792e-16
APOE 1.54751 3.32653 1.13495 2.19159 6.62930e-42 2.73180e-39
... ... ... ... ... ... ...
HNRNPA2B1 2.01947 0.953709 1.38656 -0.432852 0.985535 1.000000
HMGB1 2.42005 1.161545 1.62529 -0.463743 0.977065 1.000000
ENSMMUG00000041076 2.90478 1.361042 1.83527 -0.474232 0.964707 0.993394
RPS28 3.77411 1.744062 2.24789 -0.503824 0.941601 0.978906
ENSMMUG00000012140 3.17943 1.165070 1.93062 -0.765553 0.997237 1.000000
topn2000_features_slice <- getTopHVGs(allfeatures, n=2000)
allfeatures <- modelGeneVar(whole)
allfeatures[order(allfeatures$bio, decreasing=TRUE),]
DataFrame with 21761 rows and 6 columns
mean total tech bio p.value FDR
<numeric> <numeric> <numeric> <numeric> <numeric> <numeric>
COX2 3.20818 7.38327 1.80138 5.58189 3.17251e-69 8.07721e-66
ENSMMUG00000015202 3.05643 7.01930 1.75967 5.25964 1.46456e-64 2.98302e-61
COX3 3.45263 6.20982 1.87262 4.33720 1.34914e-39 9.15979e-37
HSPB1 2.22329 5.64927 1.55555 4.09372 1.59917e-50 1.71432e-47
BMT2 2.06413 5.58766 1.51989 4.06777 3.50835e-52 4.20342e-49
... ... ... ... ... ... ...
PABPC1 2.32614 1.12469 1.58166 -0.456978 0.949084 0.985618
ENSMMUG00000001645 2.25431 1.10171 1.56382 -0.462112 0.952865 0.988487
MAMU-A 2.20016 1.08177 1.55064 -0.468871 0.956570 0.990464
SON 1.96683 1.02268 1.49797 -0.475295 0.963807 0.995291
HNRNPA2B1 2.55677 1.02860 1.64662 -0.618018 0.983219 1.000000
topn2000_features_whole <- getTopHVGs(allfeatures, n=2000)
union2000 <- c(topn2000_features_slice, topn2000_features_whole)
intersect2000 <- intersect(topn2000_features_slice, topn2000_features_whole)
length(intersect2000)
[1] 1245
combined_intersect <- combined_result
combined_intersect <- combined_intersect[rownames(combined_intersect) %in% intersect2000,]
combined_union <- combined_result
combined_union <- combined_union[rownames(combined_union) %in% intersect2000,]
corr_mat <- round(cor(combined_union),5)
corr_mat <- corr_mat[, colnames(slice_result)]
corr_mat <- corr_mat[colnames(whole_result), ]
heatmap_data <- data.frame(clusters <- rownames(corr_mat))
heatmap_data$cell_group <- ifelse(heatmap_data$clusters %in% c("w_PECAM1high_CAV1high_ESAMhigh_LEC", "w_PECAM1high_NT5E+_LEC", "w_PECAM1low_CCL20high_LEC", "s_PECAM1low_EFNB2high_LEC", "s_PECAM1high_CAV1high_LEC", "s_LYVE1+_LEC"), "Endothelial",
ifelse(heatmap_data$clusters %in% c("s_PI16+_Fibroblasts", "s_CCL19high_Fibroblasts", "s_PTPRGhigh_Fibroblasts", "s_CXCL12high_Fibroblasts", "s_CXCL12high_HDAC11+_Fibroblasts", "w_PTPRGhigh_Fibroblasts", "w_CXCL12high_Fibroblasts", "w_CCL19high_Fibroblasts", "w_PI16+_Fibroblasts"), "Fibroblasts",
ifelse(heatmap_data$clusters %in% c("s_T_cells", "s_B_cells", "s_BCL6high_cycling_B_cells", "s_Cycling_B_cells", "s_Plasma_cells", "w_ribo_high_T_cells", "w_T_regulatory_cells", "w_CD8_T_cells", "w_S100A6high_T_cells", "w_NK_cells", "w_Cycling_T_cells", "w_B_cells", "w_mito_high_T_and_B_cells", "w_Plasma_cells"), "Lymphoid",
ifelse(heatmap_data$clusters %in% c("w_Myofibroblasts", "w_Pericytes", "s_ITGA1high_ZEB2high_Pericytes", "s_Pericytes", "s_HDAC11+_cycling_Pericytes", "s_Myofibroblasts", "s_PEAR1+_Pericytes"), "Pericytes",
ifelse(heatmap_data$clusters %in% c("s_LAMP3+_CCL17high_DCs", "CLEC9Ahigh_DCs", "s_XCR1+_CLEC9Ahigh_DCs", "s_Neutrophils", "s_Mast_cells", "s_CD14+_Monocytes", "s_LAMP3+_DCs", "s_pDCs", "w_pDCs", "w_CD1C+_DCs", "w_XCR1+_DCs", "w_Mast_cells", "w_LAMP3+_DCs", "w_Neutrophils", "w_mito_high_myeloid", "w_CD14+_monocytes", "w_CD16+_monocytes"), "Myeloid",
"-")))))
heatmap_data1 <- data.frame(clusters <- colnames(corr_mat))
colnames(heatmap_data1) <- c("clusters")
heatmap_data1$cell_group <- ifelse(heatmap_data$clusters %in% c("w_PECAM1high_CAV1high_ESAMhigh_LEC", "w_PECAM1high_NT5E+_LEC", "w_PECAM1low_CCL20high_LEC", "s_PECAM1low_EFNB2high_LEC", "s_PECAM1high_CAV1high_LEC", "s_LYVE1+_LEC"), "Endothelial",
ifelse(heatmap_data$clusters %in% c("s_PI16+_Fibroblasts", "s_CCL19high_Fibroblasts", "s_PTPRGhigh_Fibroblasts", "s_CXCL12high_Fibroblasts", "s_CXCL12high_HDAC11+_Fibroblasts", "w_PTPRGhigh_Fibroblasts", "w_CXCL12high_Fibroblasts", "w_CCL19high_Fibroblasts", "w_PI16+_Fibroblasts"), "Fibroblasts",
ifelse(heatmap_data$clusters %in% c("s_T_cells", "s_B_cells", "s_BCL6high_cycling_B_cells", "s_Cycling_B_cells", "s_Plasma_cells", "w_ribo_high_T_cells", "w_T_regulatory_cells", "w_CD8_T_cells", "w_S100A6high_T_cells", "w_NK_cells", "w_Cycling_T_cells", "w_B_cells", "w_mito_high_T_and_B_cells", "w_Plasma_cells"), "Lymphoid",
ifelse(heatmap_data$clusters %in% c("w_Myofibroblasts", "w_Pericytes", "s_ITGA1high_ZEB2high_Pericytes", "s_Pericytes", "s_HDAC11+_cycling_Pericytes", "s_Myofibroblasts", "s_PEAR1+_Pericytes"), "Pericytes",
ifelse(heatmap_data$clusters %in% c("s_LAMP3+_CCL17high_DCs", "CLEC9Ahigh_DCs", "s_XCR1+_CLEC9Ahigh_DCs", "s_Neutrophils", "s_Mast_cells", "s_CD14+_Monocytes", "s_LAMP3+_DCs", "s_pDCs", "w_pDCs", "w_CD1C+_DCs", "w_XCR1+_DCs", "w_Mast_cells", "w_LAMP3+_DCs", "w_Neutrophils", "w_mito_high_myeloid", "w_CD14+_monocytes", "w_CD16+_monocytes"), "Myeloid",
"-")))))
Error in `$<-.data.frame`(`*tmp*`, cell_group, value = c("Lymphoid", "Lymphoid", :
replacement has 27 rows, data has 26

dev.off()
Error in dev.off() : cannot shut down device 1 (the null device)

SingleR - using the whole dataset as a referance to name the
slices
slice1 <- SingleR(test = slice, ref = whole, labels = whole$subcluster_name, de.method="wilcox")
png("/Users/nityagupta/Desktop/GM project/code/singleR_heatmap.png",width=14,height=7,units="in",res=1200)
plotScoreHeatmap(slice1)
Warning: useNames = NA is deprecated. Instead, specify either useNames = TRUE or useNames = TRUE.Warning: useNames = NA is deprecated. Instead, specify either useNames = TRUE or useNames = TRUE.Warning: useNames = NA is deprecated. Instead, specify either useNames = TRUE or useNames = TRUE.
dev.off()
null device
1

plotDeltaDistribution(slice1, ncol = 4, size = 1)
ggsave("singleR_delta_distribution.png", dpi = 300, width = 9)

slice$pruned.labels <- slice1$pruned.labels
dittoDimPlot(slice, "subcluster_name", do.label = TRUE, labels.size = 3, legend.size = 6, legend.title = "Cell Type")
dittoDimPlot(slice, "labels", do.label = TRUE, labels.size = 3, legend.size = 6, legend.title = "Cell Type")
dittoDimPlot(slice, "pruned.labels", do.label = TRUE, labels.size = 3, legend.size = 6, legend.title = "Cell Type")
library(RColorBrewer)
n <- 60
qual_col_pals = brewer.pal.info[brewer.pal.info$category == 'qual',]
col_vector = unlist(mapply(brewer.pal, qual_col_pals$maxcolors, rownames(qual_col_pals)))
pie(rep(1,n), col=sample(col_vector, n))


slice_df2 <- slice_df1
slice_df2$Frequency <- 10
ggplot(slice_df2,
aes(axis1 = subcluster_name,
axis2 = labels,
y = Frequency)) +
geom_alluvium(aes(fill = match))+
geom_stratum() +
geom_label(stat = "stratum", aes(label = after_stat(stratum)), label.size = 0.01) +
scale_x_discrete(limits = c("Manual Annotation", "SingleR Annotation"),
expand = c(.1, .1)) +
labs(y = "Frequency") +
theme(axis.text.y = element_text(size = 50))+
theme_minimal()
Alluvial plot for fibroblasts

Alluvial plot for endothelial



diff_abundance_w <- as.data.frame(table(whole_da$sample_id, whole_da$subcluster_name))
diff_abundance_s <- as.data.frame(table(slice_da$sample_id, slice_da$subcluster_name))
diff_abundance <- rbind(diff_abundance_w, diff_abundance_s)
colnames(diff_abundance) <- c("sample_id", "cell_type", "number_of_cells")
diff_abundance <- separate(data = diff_abundance, col = "sample_id", c('donor_id', 'sample_type'), sep = "_", remove = FALSE)
diff_abundance$donor_id <- as.factor(diff_abundance$donor_id)
diff_abundance$sample_id <- as.factor(diff_abundance$sample_id)
diff_abundance$sample_type <- as.factor(diff_abundance$sample_type)
diff_abundance
Differential Abundance
whole_da <- whole[,whole$cluster_name %in% c("Fibroblasts", "Endothelial_cells", "Myeloid_cells", "Pericytes")]
slice_da <- slice[,slice$cluster_name %in% c("Fibroblasts", "Endothelial_cells", "Myeloid_cells", "Pericytes")]
whole_da <- colData(whole_da)
slice_da <- colData(slice_da)
whole_da <- whole_da[whole_da$donor_id %in% c("PrLN4", "PrLN5", "PrLN6"), ]
slice_da <- slice_da[slice_da$sample_id %in% c("PrLN4_sCTRL", "PrLN5_sCTRL", "PrLN6_sCTRL"),]
whole_da$sample_id <- droplevels(whole_da$sample_id)
whole_da$sample_type <- droplevels(whole_da$sample_type)
whole_da$donor_id <- droplevels(whole_da$donor_id)
slice_da$sample_id <- droplevels(slice_da$sample_id)
slice_da$sample_type <- droplevels(slice_da$sample_type)
table(whole_da$donor_id)
PrLN4 PrLN5 PrLN6
6142 1766 7516
table(slice_da$sample_id)
PrLN4_sCTRL PrLN5_sCTRL PrLN6_sCTRL
3736 4155 3240
table(whole_da$sample_type)
wCTRL
15424
table(whole_da$sample_id)
PrLN4_wCTRL PrLN5_wCTRL PrLN6_wCTRL
6142 1766 7516
table(slice_da$sample_type)
sCTRL
11131
diff_abundance_w <- as.data.frame(table(whole_da$sample_id, whole_da$subcluster_name))
diff_abundance_s <- as.data.frame(table(slice_da$sample_id, slice_da$subcluster_name))
diff_abundance <- rbind(diff_abundance_w, diff_abundance_s)
colnames(diff_abundance) <- c("sample_id", "cell_type", "number_of_cells")
diff_abundance <- separate(data = diff_abundance, col = "sample_id", c('donor_id', 'sample_type'), sep = "_", remove = FALSE)
diff_abundance$donor_id <- as.factor(diff_abundance$donor_id)
diff_abundance$sample_id <- as.factor(diff_abundance$sample_id)
diff_abundance$sample_type <- as.factor(diff_abundance$sample_type)
diff_abundance
to calculate the percentage we divide by the total number of cells in
the sample
cells_per_sample <- rbind(data.frame(table(slice_da$sample_id)), data.frame(table(whole_da$sample_id)))
colnames(cells_per_sample) <- c("sample_id", "cells_per_sample")
cells_per_sample
matching_rows <- match(diff_abundance$sample_id, cells_per_sample$sample_id)
diff_abundance$cells_per_sample <- cells_per_sample$cells_per_sample[matching_rows]
diff_abundance
diff_abundance$percentage_cells <- diff_abundance$number_of_cells/diff_abundance$cells_per_sample
diff_abundance
diff_abundance <- diff_abundance %>%
mutate(category = recode(cell_type, "CD14+_Monocytes" = "CD14+_monocytes"))
diff_abundance$cell_type[diff_abundance$cell_type == "CD14+_Monocytes"] <- "CD14+_monocytes"
ggplot(diff_abundance, aes(x = factor(cell_type, level = c("CD14+_monocytes", "CD16+_monocytes", "Neutrophils", "Mast_cells", "CD1C+_DCs", "CLEC9Ahigh_DCs", "XCR1+_CLEC9Ahigh_DCs", "XCR1+_DCs", "LAMP3+_DCs", "LAMP3+_CCL17high_DCs", "pDCs", "mito_high_myeloid", "PECAM1high_CAV1high_ESAMhigh_LEC", "PECAM1high_NT5E+_LEC", "PECAM1low_CCL20high_LEC", "PECAM1high_CAV1high_LEC", "PECAM1low_EFNB2high_LEC","LYVE1+_LEC", "CCL19high_Fibroblasts", "CXCL12high_Fibroblasts", "CXCL12high_HDAC11+_Fibroblasts","PI16+_Fibroblasts", "PTPRGhigh_Fibroblasts", "Pericytes", "ITGA1high_ZEB2high_Pericytes","HDAC11+_cycling_Pericytes", "PEAR1+_Pericytes", "Myofibroblasts")), y = percentage_cells, fill = sample_type)) +
geom_boxplot() +
labs(x = "Cell Type", y = "Proportion of cells (average across donors)", fill = "Treatment") +
theme(text = element_text(size = 15), axis.text.x = element_text(angle = 55, hjust = 1)) +
scale_fill_manual(values=c("#E78AC3", "#A1D99B"))

ggplot(diff_abundance, aes(x = factor(cell_type, level = c("CD14+_monocytes", "CD16+_monocytes", "Neutrophils", "Mast_cells", "CD1C+_DCs", "CLEC9Ahigh_DCs", "XCR1+_CLEC9Ahigh_DCs", "XCR1+_DCs", "LAMP3+_DCs", "LAMP3+_CCL17high_DCs", "pDCs", "mito_high_myeloid", "PECAM1high_CAV1high_ESAMhigh_LEC", "PECAM1high_NT5E+_LEC", "PECAM1low_CCL20high_LEC", "PECAM1high_CAV1high_LEC", "PECAM1low_EFNB2high_LEC","LYVE1+_LEC", "CCL19high_Fibroblasts", "CXCL12high_Fibroblasts", "CXCL12high_HDAC11+_Fibroblasts","PI16+_Fibroblasts", "PTPRGhigh_Fibroblasts", "Pericytes", "ITGA1high_ZEB2high_Pericytes","HDAC11+_cycling_Pericytes", "PEAR1+_Pericytes", "Myofibroblasts")), y = percentage_cells, fill = sample_type)) +
geom_boxplot() +
labs(x = "Cell Type", y = "Proportion of cells (average across donors)", fill = "Sample Type", col = "Sample ID") +
theme(text = element_text(size = 15), axis.text.x = element_text(angle = 55, hjust = 1),panel.background = element_rect(fill = "white", colour ="darkgray", size = 2), panel.grid.major = element_line(colour = "gray", size = 0.3))+
scale_fill_manual(values=c("#E78AC3", "#A1D99B"))+
geom_point(aes(col = sample_id), size = 2)
Warning: The `size` argument of `element_rect()` is deprecated as of ggplot2 3.4.0.
Please use the `linewidth` argument instead.Warning: The `size` argument of `element_line()` is deprecated as of ggplot2 3.4.0.
Please use the `linewidth` argument instead.

NA
diff_abundance1 = diff_abundance[diff_abundance$cell_type %in% c("CD14+_monocytes", "Neutrophils", "Mast_cells", "LAMP3+_DCs", "pDCs", "CCL19high_Fibroblasts", "CXCL12high_Fibroblasts","PI16+_Fibroblasts", "PTPRGhigh_Fibroblasts", "Pericytes", "Myofibroblasts"),]
cd19.model <- lm(percentage_cells ~ cell_type + sample_type, data = diff_abundance1)
temp <- diff_abundance1 %>%
group_by(cell_type) %>%
anova_test(percentage_cells ~ sample_type, error = cd19.model)
temp
cd19.model <- lm(percentage_cells ~ cell_type*sample_type, data = diff_abundance1)
temp1 <- diff_abundance1 %>%
group_by(cell_type) %>%
anova_test(percentage_cells ~ sample_type, error = cd19.model)
temp1
pwc <- diff_abundance1 %>%
group_by(cell_type) %>%
emmeans_test(percentage_cells ~ sample_type, p.adjust.method = "bonferroni")
pwc
pwc1 <- subset(pwc, select = c(cell_type, statistic, p))
pwc1 <- pwc1[order(pwc1$p),]
colnames(pwc1) <- c("cell_type", "statistic", "p_value")
pwc1
diff_abundance_w <- as.data.frame(table(whole_da$sample_id, whole_da$cluster_name))
diff_abundance_s <- as.data.frame(table(slice_da$sample_id, slice_da$cluster_name))
diff_abundance <- rbind(diff_abundance_w, diff_abundance_s)
colnames(diff_abundance) <- c("sample_id", "cell_type", "number_of_cells")
diff_abundance <- separate(data = diff_abundance, col = "sample_id", c('donor_id', 'sample_type'), sep = "_", remove = FALSE)
diff_abundance$donor_id <- as.factor(diff_abundance$donor_id)
diff_abundance$sample_id <- as.factor(diff_abundance$sample_id)
diff_abundance$sample_type <- as.factor(diff_abundance$sample_type)
diff_abundance
to calculate the percentage we divide by the total number of cells in
the sample
cells_per_sample <- rbind(data.frame(table(slice_da$sample_id)), data.frame(table(whole_da$sample_id)))
colnames(cells_per_sample) <- c("sample_id", "cells_per_sample")
cells_per_sample
matching_rows <- match(diff_abundance$sample_id, cells_per_sample$sample_id)
diff_abundance$cells_per_sample <- cells_per_sample$cells_per_sample[matching_rows]
diff_abundance
diff_abundance$percentage_cells <- diff_abundance$number_of_cells/diff_abundance$cells_per_sample
diff_abundance
NA
cd19.model <- lm(percentage_cells ~ cell_type + sample_type, data = diff_abundance)
temp <- diff_abundance %>%
group_by(cell_type) %>%
anova_test(percentage_cells ~ sample_type, error = cd19.model)
temp
cd19.model <- lm(percentage_cells ~ cell_type*sample_type, data = diff_abundance)
temp1 <- diff_abundance %>%
group_by(cell_type) %>%
anova_test(percentage_cells ~ sample_type, error = cd19.model)
temp1
pwc <- diff_abundance %>%
group_by(cell_type) %>%
emmeans_test(percentage_cells ~ sample_type, p.adjust.method = "bonferroni")
pwc
NA
NA
ggplot(diff_abundance, aes(x = cell_type, y = percentage_cells, fill = sample_type)) +
geom_boxplot() +
labs(x = "Cell Type", y = "Proportion of cells (average across donors)", fill = "Treatment", col = "Sample ID") +
theme(text = element_text(size = 15), axis.text.x = element_text(angle = 55, hjust = 1)) +
scale_fill_manual(values=c("#E78AC3", "#A1D99B"))+
geom_point(aes(col = sample_id), size = 2)

ggplot(diff_abundance, aes(x = cell_type, y = percentage_cells, fill = sample_type)) +
geom_boxplot() +
labs(x = "Cell Type", y = "Proportion of cells (average across donors)", fill = "Sample Type", col = "Sample ID") +
theme(text = element_text(size = 15), axis.text.x = element_text(angle = 55, hjust = 1),panel.background = element_rect(fill = "white", colour ="darkgray", size = 2), panel.grid.major = element_line(colour = "gray", size = 0.3))+
scale_fill_manual(values=c("#E78AC3", "#A1D99B"))+
geom_point(aes(col = sample_id), size = 2)

#+geom_signif(stat = "identity", data = data.frame(x = c(0.12, 0.37), xend = c(0.17, ), y = c(0.4, 0.39), annotation = c("*", "**")), aes(x = x, xend = xend, y = y, yend = y, annotation = annotation))
cd19.model <- lm(percentage_cells ~ cell_type + sample_type, data = diff_abundance)
temp <- diff_abundance %>%
group_by(cell_type) %>%
anova_test(percentage_cells ~ sample_type, error = cd19.model)
temp
cd19.model <- lm(percentage_cells ~ cell_type*sample_type, data = diff_abundance)
temp1 <- diff_abundance %>%
group_by(cell_type) %>%
anova_test(percentage_cells ~ sample_type, error = cd19.model)
temp1
pwc <- diff_abundance %>%
group_by(cell_type) %>%
emmeans_test(percentage_cells ~ sample_type, p.adjust.method = "bonferroni")
pwc
pwc1 <- subset(pwc, select = c(cell_type, statistic, p))
pwc1 <- pwc1[order(pwc1$p),]
colnames(pwc1) <- c("cell_type", "statistic", "p_value")
pwc1
whole_da <- whole[,whole$cluster_name %in% c("Fibroblasts", "Endothelial_cells", "Myeloid_cells", "Pericytes")]
slice_da <- slice[,slice$cluster_name %in% c("Fibroblasts", "Endothelial_cells", "Myeloid_cells", "Pericytes")]
whole_da <- whole_da[whole_da$donor_id %in% c("PrLN4", "PrLN5", "PrLN6"), ]
slice_da <- slice_da[slice_da$sample_id %in% c("PrLN4_sCTRL", "PrLN5_sCTRL", "PrLN6_sCTRL"),]
Error in intI(i, n = x@Dim[1], dn[[1]], give.dn = FALSE) :
logical subscript too long (25157, should be 21761)
LS0tCnRpdGxlOiAiV2hvbGUgU2xpY2UgQ29tcGFyaXNvbnMiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCmBgYHtyfQp3aG9sZSA8LSByZWFkUkRTKCJQcl93aG9sZV9maWx0ZXJlZF9hbm5vdGF0ZWRfZmluYWwucmRzIikKc2xpY2UgPC0gcmVhZFJEUygiUHJfc2xpY2VfZGVjb250WF9maWx0ZXJlZF9hbm5vdGF0ZWRfZmluYWwxLnJkcyIpCmBgYAoKCmBgYHtyfQp3aG9sZSA8LSByZWFkUkRTKCIvVXNlcnMvbml0eWFndXB0YS9EZXNrdG9wL0dNIHByb2plY3QvYmVzdF9vYmplY3RzL1ByTE5fd2hvbGVfcWNfYW5ub3RhdGVkX2ZpbmFsLnJkcyIpCnNsaWNlIDwtIHJlYWRSRFMoIi9Vc2Vycy9uaXR5YWd1cHRhL0Rlc2t0b3AvR00gcHJvamVjdC9iZXN0X29iamVjdHMvUHJfc2xpY2VfZGVjb250WDAuOV9maW5hbF9uZXdVTUFQLnJkcyIpCmBgYAoKCgpgYGB7ciwgZmlnLndpZHRoPTE4fQpkaXR0b0RpbVBsb3Qod2hvbGUsICJzdWJjbHVzdGVyX25hbWUiLCBkby5sYWJlbCA9IFRSVUUpCmRpdHRvRGltUGxvdChzbGljZSwgInN1YmNsdXN0ZXJfbmFtZSIsIGRvLmxhYmVsID0gVFJVRSkKYGBgCgojIyMgQ29tcGFyaW5nIHNpbWlsYXIgY2x1c3RlcnMgYmV0d2VlbiB3aG9sZSBhbmQgc2xpY2VzCgpgYGB7cn0Kd2hvbGVfY2x1c3RlcnMgPC0gdW5pcXVlKHdob2xlJHN1YmNsdXN0ZXJfbmFtZSkKd2hvbGVfcmVzdWx0IDwtIGRhdGEuZnJhbWUocm93Lm5hbWVzID0gcm93bmFtZXMod2hvbGUpKQoKCmZvciAoc3ViY2x1c3Rlcl9uYW1lIGluIHdob2xlX2NsdXN0ZXJzKSB7CiAgc3Vic2V0IDwtIHdob2xlWywgd2hvbGUkc3ViY2x1c3Rlcl9uYW1lID09IHN1YmNsdXN0ZXJfbmFtZV0KICBjb3VudHMgPC0gYXMubWF0cml4KHN1YnNldEBhc3NheXNAZGF0YUBsaXN0RGF0YVtbImxvZ2NvdW50cyJdXSkKICBzdWJzZXRfcmVzdWx0IDwtIGFzLmRhdGEuZnJhbWUoYXBwbHkoY291bnRzLCAxLCBtZWRpYW4pKQogIGNvbG5hbWVzKHN1YnNldF9yZXN1bHQpIDwtIHN1YmNsdXN0ZXJfbmFtZQogIHdob2xlX3Jlc3VsdCA8LSBjYmluZCh3aG9sZV9yZXN1bHQsIHN1YnNldF9yZXN1bHQpCn0KCgpgYGAKCmBgYHtyfQpzbGljZV9jbHVzdGVycyA8LSB1bmlxdWUoc2xpY2Ukc3ViY2x1c3Rlcl9uYW1lKQpzbGljZV9yZXN1bHQgPC0gZGF0YS5mcmFtZShyb3cubmFtZXMgPSByb3duYW1lcyhzbGljZSkpCgoKZm9yIChzdWJjbHVzdGVyX25hbWUgaW4gc2xpY2VfY2x1c3RlcnMpIHsKICBzdWJzZXQgPC0gc2xpY2VbLCBzbGljZSRzdWJjbHVzdGVyX25hbWUgPT0gc3ViY2x1c3Rlcl9uYW1lXQogIGNvdW50cyA8LSBhcy5tYXRyaXgoc3Vic2V0QGFzc2F5c0BkYXRhQGxpc3REYXRhW1sibG9nY291bnRzIl1dKQogIHN1YnNldF9yZXN1bHQgPC0gYXMuZGF0YS5mcmFtZShhcHBseShjb3VudHMsIDEsIG1lZGlhbikpCiAgY29sbmFtZXMoc3Vic2V0X3Jlc3VsdCkgPC0gc3ViY2x1c3Rlcl9uYW1lCiAgc2xpY2VfcmVzdWx0IDwtIGNiaW5kKHNsaWNlX3Jlc3VsdCwgc3Vic2V0X3Jlc3VsdCkKfQoKCmBgYAoKYGBge3J9CnNsaWNlX2NvbG5hbWVzIDwtIHBhc3RlMCgic18iLCBjb2xuYW1lcyhzbGljZV9yZXN1bHQpKQpjb2xuYW1lcyhzbGljZV9yZXN1bHQpIDwtIHNsaWNlX2NvbG5hbWVzCgp3aG9sZV9jb2xuYW1lcyA8LSBwYXN0ZTAoIndfIiwgY29sbmFtZXMod2hvbGVfcmVzdWx0KSkKY29sbmFtZXMod2hvbGVfcmVzdWx0KSA8LSB3aG9sZV9jb2xuYW1lcwoKYGBgCgpgYGB7cn0KY29tYmluZWRfcmVzdWx0IDwtIG1lcmdlKHNsaWNlX3Jlc3VsdCwgd2hvbGVfcmVzdWx0LCBieT0wKQpyb3duYW1lcyhjb21iaW5lZF9yZXN1bHQpIDwtIGNvbWJpbmVkX3Jlc3VsdCRSb3cubmFtZXMKY29tYmluZWRfcmVzdWx0JFJvdy5uYW1lcyA8LSBOVUxMCmNvbWJpbmVkX3Jlc3VsdCRzX2dlbmUgPC0gTlVMTApgYGAKCmBgYHtyfQphbGxmZWF0dXJlcyA8LSBtb2RlbEdlbmVWYXIoc2xpY2UpCmFsbGZlYXR1cmVzW29yZGVyKGFsbGZlYXR1cmVzJGJpbywgZGVjcmVhc2luZz1UUlVFKSxdIAp0b3BuMjAwMF9mZWF0dXJlc19zbGljZSA8LSBnZXRUb3BIVkdzKGFsbGZlYXR1cmVzLCBuPTIwMDApIAoKYWxsZmVhdHVyZXMgPC0gbW9kZWxHZW5lVmFyKHdob2xlKQphbGxmZWF0dXJlc1tvcmRlcihhbGxmZWF0dXJlcyRiaW8sIGRlY3JlYXNpbmc9VFJVRSksXSAKdG9wbjIwMDBfZmVhdHVyZXNfd2hvbGUgPC0gZ2V0VG9wSFZHcyhhbGxmZWF0dXJlcywgbj0yMDAwKSAKCgp1bmlvbjIwMDAgPC0gYyh0b3BuMjAwMF9mZWF0dXJlc19zbGljZSwgdG9wbjIwMDBfZmVhdHVyZXNfd2hvbGUpCmludGVyc2VjdDIwMDAgPC0gaW50ZXJzZWN0KHRvcG4yMDAwX2ZlYXR1cmVzX3NsaWNlLCB0b3BuMjAwMF9mZWF0dXJlc193aG9sZSkKbGVuZ3RoKGludGVyc2VjdDIwMDApCmBgYAoKYGBge3J9CmNvbWJpbmVkX2ludGVyc2VjdCA8LSBjb21iaW5lZF9yZXN1bHQKY29tYmluZWRfaW50ZXJzZWN0IDwtIGNvbWJpbmVkX2ludGVyc2VjdFtyb3duYW1lcyhjb21iaW5lZF9pbnRlcnNlY3QpICVpbiUgaW50ZXJzZWN0MjAwMCxdCmBgYAoKYGBge3J9CmNvbWJpbmVkX3VuaW9uIDwtIGNvbWJpbmVkX3Jlc3VsdApjb21iaW5lZF91bmlvbiA8LSBjb21iaW5lZF91bmlvbltyb3duYW1lcyhjb21iaW5lZF91bmlvbikgJWluJSBpbnRlcnNlY3QyMDAwLF0KYGBgCgpgYGB7cn0KY29ycl9tYXQgPC0gcm91bmQoY29yKGNvbWJpbmVkX3VuaW9uKSw1KQoKY29ycl9tYXQgPC0gY29ycl9tYXRbLCBjb2xuYW1lcyhzbGljZV9yZXN1bHQpXQpjb3JyX21hdCA8LSBjb3JyX21hdFtjb2xuYW1lcyh3aG9sZV9yZXN1bHQpLCBdCmBgYAoKYGBge3J9CmhlYXRtYXBfZGF0YSA8LSBkYXRhLmZyYW1lKGNsdXN0ZXJzIDwtIHJvd25hbWVzKGNvcnJfbWF0KSkKaGVhdG1hcF9kYXRhJGNlbGxfZ3JvdXAgPC0gaWZlbHNlKGhlYXRtYXBfZGF0YSRjbHVzdGVycyAlaW4lIGMoIndfUEVDQU0xaGlnaF9DQVYxaGlnaF9FU0FNaGlnaF9MRUMiLCAid19QRUNBTTFoaWdoX05UNUUrX0xFQyIsICJ3X1BFQ0FNMWxvd19DQ0wyMGhpZ2hfTEVDIiwgInNfUEVDQU0xbG93X0VGTkIyaGlnaF9MRUMiLCAic19QRUNBTTFoaWdoX0NBVjFoaWdoX0xFQyIsICJzX0xZVkUxK19MRUMiKSwgIkVuZG90aGVsaWFsIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShoZWF0bWFwX2RhdGEkY2x1c3RlcnMgJWluJSBjKCJzX1BJMTYrX0ZpYnJvYmxhc3RzIiwgInNfQ0NMMTloaWdoX0ZpYnJvYmxhc3RzIiwgInNfUFRQUkdoaWdoX0ZpYnJvYmxhc3RzIiwgInNfQ1hDTDEyaGlnaF9GaWJyb2JsYXN0cyIsICJzX0NYQ0wxMmhpZ2hfSERBQzExK19GaWJyb2JsYXN0cyIsICJ3X1BUUFJHaGlnaF9GaWJyb2JsYXN0cyIsICJ3X0NYQ0wxMmhpZ2hfRmlicm9ibGFzdHMiLCAid19DQ0wxOWhpZ2hfRmlicm9ibGFzdHMiLCAid19QSTE2K19GaWJyb2JsYXN0cyIpLCAiRmlicm9ibGFzdHMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoaGVhdG1hcF9kYXRhJGNsdXN0ZXJzICVpbiUgYygic19UX2NlbGxzIiwgInNfQl9jZWxscyIsICJzX0JDTDZoaWdoX2N5Y2xpbmdfQl9jZWxscyIsICJzX0N5Y2xpbmdfQl9jZWxscyIsICJzX1BsYXNtYV9jZWxscyIsICJ3X3JpYm9faGlnaF9UX2NlbGxzIiwgIndfVF9yZWd1bGF0b3J5X2NlbGxzIiwgIndfQ0Q4X1RfY2VsbHMiLCAid19TMTAwQTZoaWdoX1RfY2VsbHMiLCAid19OS19jZWxscyIsICJ3X0N5Y2xpbmdfVF9jZWxscyIsICJ3X0JfY2VsbHMiLCAid19taXRvX2hpZ2hfVF9hbmRfQl9jZWxscyIsICJ3X1BsYXNtYV9jZWxscyIpLCAiTHltcGhvaWQiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGhlYXRtYXBfZGF0YSRjbHVzdGVycyAlaW4lIGMoIndfTXlvZmlicm9ibGFzdHMiLCAid19QZXJpY3l0ZXMiLCAic19JVEdBMWhpZ2hfWkVCMmhpZ2hfUGVyaWN5dGVzIiwgInNfUGVyaWN5dGVzIiwgInNfSERBQzExK19jeWNsaW5nX1BlcmljeXRlcyIsICJzX015b2ZpYnJvYmxhc3RzIiwgInNfUEVBUjErX1BlcmljeXRlcyIpLCAiUGVyaWN5dGVzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShoZWF0bWFwX2RhdGEkY2x1c3RlcnMgJWluJSBjKCJzX0xBTVAzK19DQ0wxN2hpZ2hfRENzIiwgIkNMRUM5QWhpZ2hfRENzIiwgInNfWENSMStfQ0xFQzlBaGlnaF9EQ3MiLCAic19OZXV0cm9waGlscyIsICJzX01hc3RfY2VsbHMiLCAic19DRDE0K19Nb25vY3l0ZXMiLCAic19MQU1QMytfRENzIiwgInNfcERDcyIsICJ3X3BEQ3MiLCAid19DRDFDK19EQ3MiLCAid19YQ1IxK19EQ3MiLCAid19NYXN0X2NlbGxzIiwgIndfTEFNUDMrX0RDcyIsICJ3X05ldXRyb3BoaWxzIiwgIndfbWl0b19oaWdoX215ZWxvaWQiLCAid19DRDE0K19tb25vY3l0ZXMiLCAid19DRDE2K19tb25vY3l0ZXMiKSwgIk15ZWxvaWQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIi0iKSkpKSkKCgogICAgICAgCmhlYXRtYXBfZGF0YTEgPC0gZGF0YS5mcmFtZShjbHVzdGVycyA8LSBjb2xuYW1lcyhjb3JyX21hdCkpCmNvbG5hbWVzKGhlYXRtYXBfZGF0YTEpIDwtIGMoImNsdXN0ZXJzIikKaGVhdG1hcF9kYXRhMSRjZWxsX2dyb3VwIDwtIGlmZWxzZShoZWF0bWFwX2RhdGExJGNsdXN0ZXJzICVpbiUgYygid19QRUNBTTFoaWdoX0NBVjFoaWdoX0VTQU1oaWdoX0xFQyIsICJ3X1BFQ0FNMWhpZ2hfTlQ1RStfTEVDIiwgIndfUEVDQU0xbG93X0NDTDIwaGlnaF9MRUMiLCAic19QRUNBTTFsb3dfRUZOQjJoaWdoX0xFQyIsICJzX1BFQ0FNMWhpZ2hfQ0FWMWhpZ2hfTEVDIiwgInNfTFlWRTErX0xFQyIpLCAiRW5kb3RoZWxpYWwiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGhlYXRtYXBfZGF0YTEkY2x1c3RlcnMgJWluJSBjKCJzX1BJMTYrX0ZpYnJvYmxhc3RzIiwgInNfQ0NMMTloaWdoX0ZpYnJvYmxhc3RzIiwgInNfUFRQUkdoaWdoX0ZpYnJvYmxhc3RzIiwgInNfQ1hDTDEyaGlnaF9GaWJyb2JsYXN0cyIsICJzX0NYQ0wxMmhpZ2hfSERBQzExK19GaWJyb2JsYXN0cyIsICJ3X1BUUFJHaGlnaF9GaWJyb2JsYXN0cyIsICJ3X0NYQ0wxMmhpZ2hfRmlicm9ibGFzdHMiLCAid19DQ0wxOWhpZ2hfRmlicm9ibGFzdHMiLCAid19QSTE2K19GaWJyb2JsYXN0cyIpLCAiRmlicm9ibGFzdHMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoaGVhdG1hcF9kYXRhMSRjbHVzdGVycyAlaW4lIGMoInNfVF9jZWxscyIsICJzX0JfY2VsbHMiLCAic19CQ0w2aGlnaF9jeWNsaW5nX0JfY2VsbHMiLCAic19DeWNsaW5nX0JfY2VsbHMiLCAic19QbGFzbWFfY2VsbHMiLCAid19yaWJvX2hpZ2hfVF9jZWxscyIsICJ3X1RfcmVndWxhdG9yeV9jZWxscyIsICJ3X0NEOF9UX2NlbGxzIiwgIndfUzEwMEE2aGlnaF9UX2NlbGxzIiwgIndfTktfY2VsbHMiLCAid19DeWNsaW5nX1RfY2VsbHMiLCAid19CX2NlbGxzIiwgIndfbWl0b19oaWdoX1RfYW5kX0JfY2VsbHMiLCAid19QbGFzbWFfY2VsbHMiKSwgIkx5bXBob2lkIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShoZWF0bWFwX2RhdGExJGNsdXN0ZXJzICVpbiUgYygid19NeW9maWJyb2JsYXN0cyIsICJ3X1BlcmljeXRlcyIsICJzX0lUR0ExaGlnaF9aRUIyaGlnaF9QZXJpY3l0ZXMiLCAic19QZXJpY3l0ZXMiLCAic19IREFDMTErX2N5Y2xpbmdfUGVyaWN5dGVzIiwgInNfTXlvZmlicm9ibGFzdHMiLCAic19QRUFSMStfUGVyaWN5dGVzIiksICJQZXJpY3l0ZXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGhlYXRtYXBfZGF0YTEkY2x1c3RlcnMgJWluJSBjKCJzX0xBTVAzK19DQ0wxN2hpZ2hfRENzIiwgInNfQ0xFQzlBaGlnaF9EQ3MiLCAic19YQ1IxK19DTEVDOUFoaWdoX0RDcyIsICJzX05ldXRyb3BoaWxzIiwgInNfTWFzdF9jZWxscyIsICJzX0NEMTQrX01vbm9jeXRlcyIsICJzX0xBTVAzK19EQ3MiLCAic19wRENzIiwgIndfcERDcyIsICJ3X0NEMUMrX0RDcyIsICJ3X1hDUjErX0RDcyIsICJ3X01hc3RfY2VsbHMiLCAid19MQU1QMytfRENzIiwgIndfTmV1dHJvcGhpbHMiLCAid19taXRvX2hpZ2hfbXllbG9pZCIsICJ3X0NEMTQrX21vbm9jeXRlcyIsICJ3X0NEMTYrX21vbm9jeXRlcyIpLCAiTXllbG9pZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiLSIpKSkpKQoKCgpgYGAKCmBgYHtyLCBmaWcud2lkdGg9MTV9CkhlYXRtYXAoY29ycl9tYXQsIHJvd19zcGxpdCA9IGhlYXRtYXBfZGF0YSRjZWxsX2dyb3VwLCBjb2x1bW5fc3BsaXQgPSBoZWF0bWFwX2RhdGExJGNlbGxfZ3JvdXAsIHNob3dfY29sdW1uX2RlbmQgPSBGQUxTRSwgc2hvd19yb3dfZGVuZCA9IEZBTFNFLCByb3dfdGl0bGVfcm90ID0gMCwgdG9wX2Fubm90YXRpb24gPSBIZWF0bWFwQW5ub3RhdGlvbihmb28gPSBhbm5vX2Jsb2NrKGdwID0gZ3BhcihmaWxsID0gYygiIzQ2QUNDOCIgLCAiI0ZGRDkyRiIgLCIjRTVDNDk0IiwgIiNBNkQ4NTQiLCAiI0ZENjQ2NyIpKSkpLCBsZWZ0X2Fubm90YXRpb24gPSByb3dBbm5vdGF0aW9uKGZvbyA9IGFubm9fYmxvY2soZ3AgPSBncGFyKGZpbGwgPSBjKCIjNDZBQ0M4IiAsICIjRkZEOTJGIiAsIiNFNUM0OTQiLCAiI0E2RDg1NCIsICIjRkQ2NDY3IikpKSkpCgpgYGAKCmBgYHtyLCBmaWcud2lkdGg9MTV9CgpwbmcoIi9Vc2Vycy9uaXR5YWd1cHRhL0Rlc2t0b3AvR00gcHJvamVjdC9jb2RlL3dob2xlX3NsaWNlX2Nvb3JlbGF0aW9uX2hlYXRtYXAucG5nIix3aWR0aD0xMSxoZWlnaHQ9OSx1bml0cz0iaW4iLHJlcz0xMjAwKQoKSGVhdG1hcChjb3JyX21hdCwgcm93X3NwbGl0ID0gaGVhdG1hcF9kYXRhJGNlbGxfZ3JvdXAsIGNvbHVtbl9zcGxpdCA9IGhlYXRtYXBfZGF0YTEkY2VsbF9ncm91cCwgc2hvd19jb2x1bW5fZGVuZCA9IEZBTFNFLCBzaG93X3Jvd19kZW5kID0gRkFMU0UsIHJvd190aXRsZV9yb3QgPSAwLCBib3R0b21fYW5ub3RhdGlvbiA9IEhlYXRtYXBBbm5vdGF0aW9uKGZvbyA9IGFubm9fYmxvY2soZ3AgPSBncGFyKGZpbGwgPSBjKCIjRkQ2NDY3IiAsICIjRkZEOTJGIiAsIiNFNUM0OTQiLCAiI0E2RDg1NCIsICIjNDZBQ0M4IikpLCBsYWJlbHMgPSBjKCJGaWJyb2JsYXN0cyIsICJQZXJpY3l0ZXMiLCAiTEVDcyIsICJMeW1waG9pZCIsICJNeWVsb2lkIikpLCBzaG93X2xlZ2VuZCA9IGMoVFJVRSkpLCByaWdodF9hbm5vdGF0aW9uID0gcm93QW5ub3RhdGlvbihmb28gPSBhbm5vX2Jsb2NrKGdwID0gZ3BhcihmaWxsID0gYygiI0ZENjQ2NyIgLCAiI0ZGRDkyRiIgLCIjRTVDNDk0IiwgIiNBNkQ4NTQiLCAiIzQ2QUNDOCIpKSwgbGFiZWxzID0gYygiRmlicm9ibGFzdHMiLCAiUGVyaSIsICJMRUNzIiwgIkx5bXBob2lkIiwgIk15ZWxvaWQiKSkpLCBjb2x1bW5fdGl0bGUgPSBOVUxMLCByb3dfdGl0bGUgPSBOVUxMLCBuYW1lID0gIkNvcnJlbGF0aW9uIHNjb3JlIikgKyBMZWdlbmQoYXQgPSBjKCJGaWJyb2JsYXN0cyIsICJQZXJpY3l0ZXMiLCAiTEVDcyIsICJMeW1waG9pZCIsICJNeWVsb2lkIiksIHRpdGxlID0gIkNlbGwgVHlwZSIsIGxlZ2VuZF9ncCA9IGdwYXIoZmlsbCA9IGMoIiM0NkFDQzgiICwgIiNGRkQ5MkYiICwiI0U1QzQ5NCIsICIjQTZEODU0IiwgIiNGRDY0NjciKSkpCgpkZXYub2ZmKCkKCnBuZygiL1VzZXJzL25pdHlhZ3VwdGEvRGVza3RvcC9HTSBwcm9qZWN0L2NvZGUvd2hvbGVfc2xpY2VfY29vcmVsYXRpb25faGVhdG1hcF9sZWdlbmQucG5nIix3aWR0aD0xMSxoZWlnaHQ9OSx1bml0cz0iaW4iLHJlcz0xMjAwKQpsID0gTGVnZW5kKGF0ID0gYygiRmlicm9ibGFzdHMiLCAiUGVyaWN5dGVzIiwgIkVuZG90aGVsaWFsIGNlbGxzIChMRUNzKSIsICJMeW1waG9pZCBjZWxscyIsICJNeWVsb2lkIGNlbGxzIiksIHRpdGxlID0gIkNlbGwgVHlwZSIsIGxlZ2VuZF9ncCA9IGdwYXIoZmlsbCA9IGMoIiM0NkFDQzgiICwgIiNGRkQ5MkYiICwiI0U1QzQ5NCIsICIjQTZEODU0IiwgIiNGRDY0NjciKSkpCmRyYXcobCkKZGV2Lm9mZigpCgoKYGBgCgoKCgoKYGBge3J9CmhhID0gSGVhdG1hcEFubm90YXRpb24oZm9vID0gYW5ub19ibG9jayhncCA9IGdwYXIoZmlsbCA9IGMoIiM0NkFDQzgiICwgIiNGRkQ5MkYiICwiI0U1QzQ5NCIsICIjQTZEODU0IiwgIiNGRDY0NjciKSksIGxhYmVscyA9IGMoIkZpYnJvYmxhc3RzIiwgIlBlcmljeXRlcyIsICJMRUNzIiwgIkx5bXBob2lkIiwgIk15ZWxvaWQiKSksIGFubm90YXRpb25fbGVnZW5kX3BhcmFtID0gbGlzdCh0aXRsZSA9ICJDZWxsIFR5cGUiLCBhdCA9IGMoIkZpYnJvYmxhc3RzIiwgIlBlcmljeXRlcyIsICJMRUNzIiwgIkx5bXBob2lkIiwgIk15ZWxvaWQiKSwgbGFiZWxzID0gYygiRmlicm9ibGFzdHMiLCAiUGVyaWN5dGVzIiwgIkxFQ3MiLCAiTHltcGhvaWQiLCAiTXllbG9pZCIpKSwgc2hvd19sZWdlbmQgPSBUUlVFKQoKSGVhdG1hcChjb3JyX21hdCwgcm93X3NwbGl0ID0gaGVhdG1hcF9kYXRhJGNlbGxfZ3JvdXAsIGNvbHVtbl9zcGxpdCA9IGhlYXRtYXBfZGF0YTEkY2VsbF9ncm91cCwgc2hvd19jb2x1bW5fZGVuZCA9IEZBTFNFLCBzaG93X3Jvd19kZW5kID0gRkFMU0UsIHJvd190aXRsZV9yb3QgPSAwLCBib3R0b21fYW5ub3RhdGlvbiA9IGhhLCByaWdodF9hbm5vdGF0aW9uID0gcm93QW5ub3RhdGlvbihmb28gPSBhbm5vX2Jsb2NrKGdwID0gZ3BhcihmaWxsID0gYygiI0ZENjQ2NyIgLCAiI0ZGRDkyRiIgLCIjRTVDNDk0IiwgIiNBNkQ4NTQiLCAiIzQ2QUNDOCIpKSwgbGFiZWxzID0gYygiRmlicm9ibGFzdHMiLCAiUGVyaSIsICJMRUNzIiwgIkx5bXBob2lkIiwgIk15ZWxvaWQiKSkpLCBjb2x1bW5fdGl0bGUgPSBOVUxMLCByb3dfdGl0bGUgPSBOVUxMLCBuYW1lID0gIkNvcnJlbGF0aW9uIHNjb3JlIikgKyBMZWdlbmQoYXQgPSBjKCJGaWJyb2JsYXN0cyIsICJQZXJpY3l0ZXMiLCAiTEVDcyIsICJMeW1waG9pZCIsICJNeWVsb2lkIiksIHRpdGxlID0gIkNlbGwgVHlwZSIsIGxlZ2VuZF9ncCA9IGdwYXIoZmlsbCA9IGMoIiM0NkFDQzgiICwgIiNGRkQ5MkYiICwiI0U1QzQ5NCIsICIjQTZEODU0IiwgIiNGRDY0NjciKSkpCmBgYAoKCiMjIyBTaW5nbGVSIC0gdXNpbmcgdGhlIHdob2xlIGRhdGFzZXQgYXMgYSByZWZlcmFuY2UgdG8gbmFtZSB0aGUgc2xpY2VzCgpgYGB7cn0Kc2xpY2UxIDwtIFNpbmdsZVIodGVzdCA9IHNsaWNlLCByZWYgPSB3aG9sZSwgbGFiZWxzID0gd2hvbGUkc3ViY2x1c3Rlcl9uYW1lLCBkZS5tZXRob2Q9IndpbGNveCIpCmBgYAoKYGBge3IsIGZpZy53aWR0aD0yMH0KcG5nKCIvVXNlcnMvbml0eWFndXB0YS9EZXNrdG9wL0dNIHByb2plY3QvY29kZS9zaW5nbGVSX2hlYXRtYXAucG5nIix3aWR0aD0xNCxoZWlnaHQ9Nyx1bml0cz0iaW4iLHJlcz0xMjAwKQpwbG90U2NvcmVIZWF0bWFwKHNsaWNlMSkKZGV2Lm9mZigpCmBgYAoKYGBge3IsIGZpZy5oZWlnaHQ9MjV9CmNlbGx0eXBlX21lYW4gPC0gYWdncmVnYXRlQWNyb3NzQ2VsbHMoYXMoc2xpY2UsICJTaW5nbGVDZWxsRXhwZXJpbWVudCIpLCAgCiAgICAgICAgICAgICAgICAgICAgIGlkcyA9IHNsaWNlJGxhYmVscywgCiAgICAgICAgICAgICAgICAgICAgIHN0YXRpc3RpY3MgPSAibWVhbiIsCiAgICAgICAgICAgICAgICAgICAgIHVzZS5hc3NheS50eXBlID0gImxvZ2NvdW50cyIpCnBuZygiL1VzZXJzL25pdHlhZ3VwdGEvRGVza3RvcC9HTSBwcm9qZWN0L2NvZGUvc3Z3X2hlYXRtYXAucG5nIix3aWR0aD0xNi41LGhlaWdodD0yMix1bml0cz0iaW4iLHJlcz0xMjAwKQojIE5vIHNjYWxpbmcKCmRpdHRvSGVhdG1hcChjZWxsdHlwZV9tZWFuLAogICAgICAgICAgICAgYXNzYXkgPSAibG9nY291bnRzIiwgCiAgICAgICAgICAgICBjbHVzdGVyX2NvbHMgPSBUUlVFLCBnZW5lcyA9IHVuaXF1ZSh1bmxpc3QoYWxsLm1hcmtlcnMpKSwKICAgICAgICAgICAgIHNjYWxlID0gIm5vbmUiLAogICAgICAgICAgICAgYW5ub3QuYnkgPSAgYygiY2x1c3Rlcl9uYW1lIiwibGFiZWxzIiksIAogICAgICAgICAgICAgb3JkZXIuYnkgPSBjKCJjbHVzdGVyX25hbWUiLCJsYWJlbHMiKSwgc2NhbGVkLnRvLm1heCA9IFRSVUUpCgpkZXYub2ZmKCkKYGBgCgpgYGB7ciwgZmlnLndpZHRoPTIwfQpwbG90RGVsdGFEaXN0cmlidXRpb24oc2xpY2UxLCBuY29sID0gNCwgc2l6ZSA9IDEpIApnZ3NhdmUoInNpbmdsZVJfZGVsdGFfZGlzdHJpYnV0aW9uLnBuZyIsIGRwaSA9IDMwMCwgd2lkdGggPSA5KQpgYGAKCgpgYGB7cn0KYWxsLm1hcmtlcnMgPC0gbWV0YWRhdGEoc2xpY2UxKSRkZS5nZW5lcwpzbGljZSRsYWJlbHMgPC0gc2xpY2UxJGxhYmVscwoKIyBCZXRhIGNlbGwtcmVsYXRlZCBtYXJrZXJzCmxpYnJhcnkoc2NhdGVyKQpwbG90SGVhdG1hcChzbGljZSwgY29sdW1ucyA9ICJsYWJlbHMiLCBvcmRlcl9jb2x1bW5zX2J5PSJsYWJlbHMiLCBleHByc192YWx1ZXMgPSAibG9nY291bnRzIiwKICAgIGZlYXR1cmVzPXVuaXF1ZSh1bmxpc3QoYWxsLm1hcmtlcnMpKSkKcGxvdEhlYXRtYXAoc2NlLCBmZWF0dXJlcyA9IHRvcG4yMDAwX2ZlYXR1cmVzLCBjb2x1bW5zID0gInNhbXBsZV9pZCIpCnBsb3RIZWF0bWFwKHNjZSwgZmVhdHVyZXM9cm93bmFtZXMoc2NlKVsxOjEwXSkKCgpkaXR0b0hlYXRtYXAoc2xpY2UsIHVuaXF1ZSh1bmxpc3QoYWxsLm1hcmtlcnMpKSwgYW5ub3QuYnkgPSAibGFiZWxzIiwgb3JkZXIuYnkgPSAibGFiZWxzIikKYGBgCgoKYGBge3J9CnNsaWNlJHBydW5lZC5sYWJlbHMgPC0gc2xpY2UxJHBydW5lZC5sYWJlbHMKYGBgCgoKCmBgYHtyLCBmaWcud2lkdGg9MTV9CmRpdHRvRGltUGxvdChzbGljZSwgInN1YmNsdXN0ZXJfbmFtZSIsIGRvLmxhYmVsID0gVFJVRSwgbGFiZWxzLnNpemUgPSAzLCBsZWdlbmQuc2l6ZSA9IDYsIGxlZ2VuZC50aXRsZSA9ICJDZWxsIFR5cGUiKQpkaXR0b0RpbVBsb3Qoc2xpY2UsICJsYWJlbHMiLCBkby5sYWJlbCA9IFRSVUUsIGxhYmVscy5zaXplID0gMywgbGVnZW5kLnNpemUgPSA2LCBsZWdlbmQudGl0bGUgPSAiQ2VsbCBUeXBlIikKZGl0dG9EaW1QbG90KHNsaWNlLCAicHJ1bmVkLmxhYmVscyIsIGRvLmxhYmVsID0gVFJVRSwgbGFiZWxzLnNpemUgPSAzLCBsZWdlbmQuc2l6ZSA9IDYsIGxlZ2VuZC50aXRsZSA9ICJDZWxsIFR5cGUiKQpgYGAKCgpgYGB7ciwgZmlnLndpZHRoPTE1fQpsaWJyYXJ5KGdnYWxsdXZpYWwpCgpzbGljZV9kZiA8LSBjb2xEYXRhKHNsaWNlKQpzbGljZV9kZiA8LSBzbGljZV9kZlssYygibGFiZWxzIiwgInN1YmNsdXN0ZXJfbmFtZSIpXQpzbGljZV9kZjEgPC0gc2xpY2VfZGYgJT4lIGdyb3VwX2J5KGxhYmVscywgc3ViY2x1c3Rlcl9uYW1lKSAlPiUgc3VtbWFyaXNlKEZyZXF1ZW5jeSA9IG4oKSkKc2xpY2VfZGYxJG1hdGNoIDwtIGlmZWxzZShzbGljZV9kZjEkc3ViY2x1c3Rlcl9uYW1lID09IHNsaWNlX2RmMSRsYWJlbHMsICJZZXMiLCAiTm8iKQoKZ2dwbG90KHNsaWNlX2RmMSwKICAgICAgIGFlcyhheGlzMSA9IHN1YmNsdXN0ZXJfbmFtZSwKICAgICAgICAgICBheGlzMiA9IGxhYmVscywKICAgICAgICAgICB5ID0gRnJlcXVlbmN5KSkgKwogIGdlb21fYWxsdXZpdW0oYWVzKGZpbGwgPSBtYXRjaCkpKwogIGdlb21fc3RyYXR1bSgpICsKICBnZW9tX2xhYmVsKHN0YXQgPSAic3RyYXR1bSIsIGFlcyhsYWJlbCA9IGFmdGVyX3N0YXQoc3RyYXR1bSkpLCBsYWJlbC5zaXplID0gMC4wMSkgKwogIHNjYWxlX3hfZGlzY3JldGUobGltaXRzID0gYygiTWFudWFsIEFubm90YXRpb24iLCAiU2luZ2xlUiBBbm5vdGF0aW9uIiksCiAgICAgICAgICAgICAgICAgICBleHBhbmQgPSBjKC4xLCAuMSkpICsKICBsYWJzKHkgPSAiRnJlcXVlbmN5IikgKwogIHRoZW1lKGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCkpKwogIHRoZW1lX21pbmltYWwoKQoKYGBgCgpgYGB7cn0KbGlicmFyeShSQ29sb3JCcmV3ZXIpCm4gPC0gNjAKcXVhbF9jb2xfcGFscyA9IGJyZXdlci5wYWwuaW5mb1ticmV3ZXIucGFsLmluZm8kY2F0ZWdvcnkgPT0gJ3F1YWwnLF0KY29sX3ZlY3RvciA9IHVubGlzdChtYXBwbHkoYnJld2VyLnBhbCwgcXVhbF9jb2xfcGFscyRtYXhjb2xvcnMsIHJvd25hbWVzKHF1YWxfY29sX3BhbHMpKSkKcGllKHJlcCgxLG4pLCBjb2w9c2FtcGxlKGNvbF92ZWN0b3IsIG4pKQpgYGAKCgoKYGBge3IsIGZpZy53aWR0aD0xNX0Kc2xpY2VfZGYyIDwtIHNsaWNlX2RmMQoKc2xpY2VfZGYyJEZyZXF1ZW5jeSA8LSAxMAoKZ2dwbG90KHNsaWNlX2RmMiwKICAgICAgIGFlcyhheGlzMSA9IHN1YmNsdXN0ZXJfbmFtZSwKICAgICAgICAgICBheGlzMiA9IGxhYmVscywKICAgICAgICAgICB5ID0gRnJlcXVlbmN5KSkgKwogIGdlb21fYWxsdXZpdW0oYWVzKGZpbGwgPSBtYXRjaCkpKwogIGdlb21fc3RyYXR1bSgpICsKICBnZW9tX2xhYmVsKHN0YXQgPSAic3RyYXR1bSIsIGFlcyhsYWJlbCA9IGFmdGVyX3N0YXQoc3RyYXR1bSkpLCBsYWJlbC5zaXplID0gMC4wMSkgKwogIHNjYWxlX3hfZGlzY3JldGUobGltaXRzID0gYygiTWFudWFsIEFubm90YXRpb24iLCAiU2luZ2xlUiBBbm5vdGF0aW9uIiksCiAgICAgICAgICAgICAgICAgICBleHBhbmQgPSBjKC4xLCAuMSkpICsKICBsYWJzKHkgPSAiRnJlcXVlbmN5IikgKwogIHRoZW1lKGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSA1MCkpKwogIHRoZW1lX21pbmltYWwoKQpgYGAKCkFsbHV2aWFsIHBsb3QgZm9yIGZpYnJvYmxhc3RzCgpgYGB7cn0KZmlicm8gPC0gc2xpY2VbLHNsaWNlJGNsdXN0ZXJfbmFtZSA9PSAiRmlicm9ibGFzdHMiXQoKCnNsaWNlX2RmIDwtIGFzLmRhdGEuZnJhbWUoY29sRGF0YShmaWJybykpCnNsaWNlX2RmIDwtIHNsaWNlX2RmWyxjKCJsYWJlbHMiLCAic3ViY2x1c3Rlcl9uYW1lIildCnNsaWNlX2RmMSA8LSBzbGljZV9kZiAlPiUgZ3JvdXBfYnkoc3ViY2x1c3Rlcl9uYW1lLCBsYWJlbHMpICU+JSBzdW1tYXJpc2UoRnJlcXVlbmN5ID0gbigpKQpzbGljZV9kZjEkTWF0Y2ggPC0gaWZlbHNlKHNsaWNlX2RmMSRzdWJjbHVzdGVyX25hbWUgPT0gc2xpY2VfZGYxJGxhYmVscywgIlllcyIsICJObyIpCnNsaWNlX2RmMSA8LSBzbGljZV9kZjFbc2xpY2VfZGYxJEZyZXF1ZW5jeSA+PSAxMCwgXQpzbGljZV9kZjEkbG9nZnJlcSA8LSBsb2cxMChzbGljZV9kZjEkRnJlcXVlbmN5KQpzbGljZV9kZjEkRnJlcXVlbmN5bWF0Y2ggPC0gaWZlbHNlKHNsaWNlX2RmMSRNYXRjaCA9PSAiWWVzIiwgc2xpY2VfZGYxJEZyZXF1ZW5jeSwgMC1zbGljZV9kZjEkRnJlcXVlbmN5KQpzbGljZV9kZjEkbG9nRnJlcXVlbmN5bWF0Y2ggPC0gaWZlbHNlKHNsaWNlX2RmMSRNYXRjaCA9PSAiWWVzIiwgc2xpY2VfZGYxJGxvZ2ZyZXEsIDAtc2xpY2VfZGYxJGxvZ2ZyZXEpCgoKZ2dwbG90KHNsaWNlX2RmMSwKICAgICAgIGFlcyhheGlzMSA9IHN1YmNsdXN0ZXJfbmFtZSwKICAgICAgICAgICBheGlzMiA9IGxhYmVscywKICAgICAgICAgICB5ID0gbG9nZnJlcSkpICsKICAgIGdlb21fYWxsdXZpdW0oYWVzKGFscGhhID0gRnJlcXVlbmN5KSkgKwogIGdlb21fYWxsdXZpdW0oYWVzKGZpbGwgPSBNYXRjaCkpICsgCiAgZ2VvbV9zdHJhdHVtKCkgKwogIGdlb21fbGFiZWwoc3RhdCA9ICJzdHJhdHVtIiwgYWVzKGxhYmVsID0gYWZ0ZXJfc3RhdChzdHJhdHVtKSksIGxhYmVsLnNpemUgPSAwLjAxKSArCiAgc2NhbGVfeF9kaXNjcmV0ZShsaW1pdHMgPSBjKCJNYW51YWwgQW5ub3RhdGlvbiIsICJTaW5nbGVSIEFubm90YXRpb24iKSwKICAgICAgICAgICAgICAgICAgIGV4cGFuZCA9IGMoLjEsIC4xKSkgKwogIGxhYnMoeSA9ICJMb2cxMCBbQ2x1c3RlciBzaXplXSIsIGFscGhhID0gIk51bWJlciBvZiBDZWxscyIsIGZpbGwgPSAiQW5ub3RhdGlvbnMgbWF0Y2g/IikgKwogIHRoZW1lX21pbmltYWwoKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyNSksIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTApKQoKIytzY2FsZV9maWxsX2dyYWRpZW50Mihsb3c9InJlZCIsIG1pZD0id2hpdGUiLCBoaWdoPSJibHVlIiwgbmFtZSA9ICJsb2cxMFtDZWxsc10iLCBsaW1pdHMgPSBjKC01MDAsODUwMCkpCgoKZ2dwbG90KHNsaWNlX2RmMSwKICAgICAgIGFlcyhheGlzMSA9IHN1YmNsdXN0ZXJfbmFtZSwKICAgICAgICAgICBheGlzMiA9IGxhYmVscywKICAgICAgICAgICB5ID0gbG9nZnJlcSkpICsKICBnZW9tX2FsbHV2aXVtKGFlcyhmaWxsID0gbG9nRnJlcXVlbmN5bWF0Y2gpKSsKICBnZW9tX3N0cmF0dW0oKSArCiAgZ2VvbV9sYWJlbChzdGF0ID0gInN0cmF0dW0iLCBhZXMobGFiZWwgPSBhZnRlcl9zdGF0KHN0cmF0dW0pKSwgbGFiZWwuc2l6ZSA9IDAuMDEpICsKICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cyA9IGMoIk1hbnVhbCBBbm5vdGF0aW9uIiwgIlNpbmdsZVIgQW5ub3RhdGlvbiIpLAogICAgICAgICAgICAgICAgICAgZXhwYW5kID0gYyguMSwgLjEpKSArCiAgbGFicyh5ID0gIkxvZzEwIFtDbHVzdGVyIHNpemVdIikgKwogIHRoZW1lX21pbmltYWwoKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyNSksIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTApKSsKICBzY2FsZV9maWxsX2dyYWRpZW50MihtaWRwb2ludCA9IDEsIGxvdz0icmVkIiwgbWlkPSJvcmFuZ2UiLCBoaWdoPSJ5ZWxsb3ciLCBuYW1lID0gImxvZzEwW0NlbGxzXSIpCgpgYGAKCgpBbGx1dmlhbCBwbG90IGZvciBlbmRvdGhlbGlhbAoKCmBgYHtyfQplbmRvIDwtIHNsaWNlWyxzbGljZSRjbHVzdGVyX25hbWUgPT0gIkVuZG90aGVsaWFsX2NlbGxzIl0KCgpzbGljZV9kZiA8LSBhcy5kYXRhLmZyYW1lKGNvbERhdGEoZW5kbykpCnNsaWNlX2RmIDwtIHNsaWNlX2RmWyxjKCJsYWJlbHMiLCAic3ViY2x1c3Rlcl9uYW1lIildCnNsaWNlX2RmMSA8LSBzbGljZV9kZiAlPiUgZ3JvdXBfYnkoc3ViY2x1c3Rlcl9uYW1lLCBsYWJlbHMpICU+JSBzdW1tYXJpc2UoRnJlcXVlbmN5ID0gbigpKQpzbGljZV9kZjEkTWF0Y2ggPC0gaWZlbHNlKHNsaWNlX2RmMSRzdWJjbHVzdGVyX25hbWUgPT0gc2xpY2VfZGYxJGxhYmVscywgIlllcyIsICJObyIpCnNsaWNlX2RmMSA8LSBzbGljZV9kZjFbc2xpY2VfZGYxJEZyZXF1ZW5jeSA+PSAxMCwgXQpzbGljZV9kZjEkbG9nZnJlcSA8LSBsb2cxMChzbGljZV9kZjEkRnJlcXVlbmN5KQpzbGljZV9kZjEkRnJlcXVlbmN5bWF0Y2ggPC0gaWZlbHNlKHNsaWNlX2RmMSRNYXRjaCA9PSAiWWVzIiwgc2xpY2VfZGYxJEZyZXF1ZW5jeSwgMC1zbGljZV9kZjEkRnJlcXVlbmN5KQpzbGljZV9kZjEkbG9nRnJlcXVlbmN5bWF0Y2ggPC0gaWZlbHNlKHNsaWNlX2RmMSRNYXRjaCA9PSAiWWVzIiwgc2xpY2VfZGYxJGxvZ2ZyZXEsIDAtc2xpY2VfZGYxJGxvZ2ZyZXEpCgpnZ3Bsb3Qoc2xpY2VfZGYxLAogICAgICAgYWVzKGF4aXMxID0gc3ViY2x1c3Rlcl9uYW1lLAogICAgICAgICAgIGF4aXMyID0gbGFiZWxzLAogICAgICAgICAgIHkgPSBsb2dmcmVxKSkgKwogICAgZ2VvbV9hbGx1dml1bShhZXMoYWxwaGEgPSBGcmVxdWVuY3kpKSArCiAgZ2VvbV9hbGx1dml1bShhZXMoZmlsbCA9IE1hdGNoKSkgKyAKICBnZW9tX3N0cmF0dW0oKSArCiAgZ2VvbV9sYWJlbChzdGF0ID0gInN0cmF0dW0iLCBhZXMobGFiZWwgPSBhZnRlcl9zdGF0KHN0cmF0dW0pKSwgbGFiZWwuc2l6ZSA9IDAuMDEpICsKICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cyA9IGMoIk1hbnVhbCBBbm5vdGF0aW9uIiwgIlNpbmdsZVIgQW5ub3RhdGlvbiIpLAogICAgICAgICAgICAgICAgICAgZXhwYW5kID0gYyguMSwgLjEpKSArCiAgbGFicyh5ID0gIkxvZzEwIFtDbHVzdGVyIHNpemVdIiwgYWxwaGEgPSAiTnVtYmVyIG9mIENlbGxzIiwgZmlsbCA9ICJBbm5vdGF0aW9ucyBtYXRjaD8iKSArCiAgdGhlbWVfbWluaW1hbCgpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDI1KSwgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMCkpCgpnZ3Bsb3Qoc2xpY2VfZGYxLAogICAgICAgYWVzKGF4aXMxID0gc3ViY2x1c3Rlcl9uYW1lLAogICAgICAgICAgIGF4aXMyID0gbGFiZWxzLAogICAgICAgICAgIHkgPSBsb2dmcmVxKSkgKwogIGdlb21fYWxsdXZpdW0oYWVzKGZpbGwgPSBGcmVxdWVuY3ltYXRjaCkpKwogIGdlb21fc3RyYXR1bSgpICsKICBnZW9tX2xhYmVsKHN0YXQgPSAic3RyYXR1bSIsIGFlcyhsYWJlbCA9IGFmdGVyX3N0YXQoc3RyYXR1bSkpLCBsYWJlbC5zaXplID0gMC4wMSkgKwogIHNjYWxlX3hfZGlzY3JldGUobGltaXRzID0gYygiTWFudWFsIEFubm90YXRpb24iLCAiU2luZ2xlUiBBbm5vdGF0aW9uIiksCiAgICAgICAgICAgICAgICAgICBleHBhbmQgPSBjKC4xLCAuMSkpICsKICBsYWJzKHkgPSAiTG9nMTAgW0NsdXN0ZXIgc2l6ZV0iKSArCiAgdGhlbWVfbWluaW1hbCgpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDI1KSwgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMCkpKwogIHNjYWxlX2ZpbGxfZ3JhZGllbnQyKG1pZHBvaW50ID0gMCwgbG93PSJyZWQiLCBtaWQ9Im9yYW5nZSIsIGhpZ2g9InllbGxvdyIsIG5hbWUgPSAibG9nMTBbQ2VsbHNdIikKCgpnZ3Bsb3Qoc2xpY2VfZGYxLAogICAgICAgYWVzKGF4aXMxID0gc3ViY2x1c3Rlcl9uYW1lLAogICAgICAgICAgIGF4aXMyID0gbGFiZWxzLAogICAgICAgICAgIHkgPSBsb2dmcmVxKSkgKwogIGdlb21fYWxsdXZpdW0oYWVzKGZpbGwgPSBsb2dGcmVxdWVuY3ltYXRjaCkpKwogIGdlb21fc3RyYXR1bSgpICsKICBnZW9tX2xhYmVsKHN0YXQgPSAic3RyYXR1bSIsIGFlcyhsYWJlbCA9IGFmdGVyX3N0YXQoc3RyYXR1bSkpLCBsYWJlbC5zaXplID0gMC4wMSkgKwogIHNjYWxlX3hfZGlzY3JldGUobGltaXRzID0gYygiTWFudWFsIEFubm90YXRpb24iLCAiU2luZ2xlUiBBbm5vdGF0aW9uIiksCiAgICAgICAgICAgICAgICAgICBleHBhbmQgPSBjKC4xLCAuMSkpICsKICBsYWJzKHkgPSAiTG9nMTAgW0NsdXN0ZXIgc2l6ZV0iKSArCiAgdGhlbWVfbWluaW1hbCgpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDI1KSwgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMCkpKwogIHNjYWxlX2ZpbGxfZ3JhZGllbnQyKG1pZHBvaW50ID0gMSwgbG93PSJyZWQiLCBtaWQ9Im9yYW5nZSIsIGhpZ2g9InllbGxvdyIsIG5hbWUgPSAibG9nMTBbQ2VsbHNdIikKCmBgYAoKCmBgYHtyfQpwZXJpIDwtIHNsaWNlWyxzbGljZSRjbHVzdGVyX25hbWUgPT0gIlBlcmljeXRlcyJdCgoKc2xpY2VfZGYgPC0gYXMuZGF0YS5mcmFtZShjb2xEYXRhKHBlcmkpKQpzbGljZV9kZiA8LSBzbGljZV9kZlssYygibGFiZWxzIiwgInN1YmNsdXN0ZXJfbmFtZSIpXQpzbGljZV9kZjEgPC0gc2xpY2VfZGYgJT4lIGdyb3VwX2J5KHN1YmNsdXN0ZXJfbmFtZSwgbGFiZWxzKSAlPiUgc3VtbWFyaXNlKEZyZXF1ZW5jeSA9IG4oKSkKc2xpY2VfZGYxJE1hdGNoIDwtIGlmZWxzZShzbGljZV9kZjEkc3ViY2x1c3Rlcl9uYW1lID09IHNsaWNlX2RmMSRsYWJlbHMsICJZZXMiLCAiTm8iKQpzbGljZV9kZjEgPC0gc2xpY2VfZGYxW3NsaWNlX2RmMSRGcmVxdWVuY3kgPj0gMTAsIF0Kc2xpY2VfZGYxJGxvZ2ZyZXEgPC0gbG9nMTAoc2xpY2VfZGYxJEZyZXF1ZW5jeSkKc2xpY2VfZGYxJEZyZXF1ZW5jeW1hdGNoIDwtIGlmZWxzZShzbGljZV9kZjEkTWF0Y2ggPT0gIlllcyIsIHNsaWNlX2RmMSRGcmVxdWVuY3ksIDAtc2xpY2VfZGYxJEZyZXF1ZW5jeSkKc2xpY2VfZGYxJGxvZ0ZyZXF1ZW5jeW1hdGNoIDwtIGlmZWxzZShzbGljZV9kZjEkTWF0Y2ggPT0gIlllcyIsIHNsaWNlX2RmMSRsb2dmcmVxLCAwLXNsaWNlX2RmMSRsb2dmcmVxKQoKZ2dwbG90KHNsaWNlX2RmMSwKICAgICAgIGFlcyhheGlzMSA9IHN1YmNsdXN0ZXJfbmFtZSwKICAgICAgICAgICBheGlzMiA9IGxhYmVscywKICAgICAgICAgICB5ID0gbG9nZnJlcSkpICsKICAgIGdlb21fYWxsdXZpdW0oYWVzKGFscGhhID0gRnJlcXVlbmN5KSkgKwogIGdlb21fYWxsdXZpdW0oYWVzKGZpbGwgPSBNYXRjaCkpICsgCiAgZ2VvbV9zdHJhdHVtKCkgKwogIGdlb21fbGFiZWwoc3RhdCA9ICJzdHJhdHVtIiwgYWVzKGxhYmVsID0gYWZ0ZXJfc3RhdChzdHJhdHVtKSksIGxhYmVsLnNpemUgPSAwLjAxKSArCiAgc2NhbGVfeF9kaXNjcmV0ZShsaW1pdHMgPSBjKCJNYW51YWwgQW5ub3RhdGlvbiIsICJTaW5nbGVSIEFubm90YXRpb24iKSwKICAgICAgICAgICAgICAgICAgIGV4cGFuZCA9IGMoLjEsIC4xKSkgKwogIGxhYnMoeSA9ICJMb2cxMCBbQ2x1c3RlciBzaXplXSIsIGFscGhhID0gIk51bWJlciBvZiBDZWxscyIsIGZpbGwgPSAiQW5ub3RhdGlvbnMgbWF0Y2g/IikgKwogIHRoZW1lX21pbmltYWwoKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyNSksIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTApKQoKZ2dwbG90KHNsaWNlX2RmMSwKICAgICAgIGFlcyhheGlzMSA9IHN1YmNsdXN0ZXJfbmFtZSwKICAgICAgICAgICBheGlzMiA9IGxhYmVscywKICAgICAgICAgICB5ID0gbG9nZnJlcSkpICsKICBnZW9tX2FsbHV2aXVtKGFlcyhmaWxsID0gRnJlcXVlbmN5bWF0Y2gpKSsKICBnZW9tX3N0cmF0dW0oKSArCiAgZ2VvbV9sYWJlbChzdGF0ID0gInN0cmF0dW0iLCBhZXMobGFiZWwgPSBhZnRlcl9zdGF0KHN0cmF0dW0pKSwgbGFiZWwuc2l6ZSA9IDAuMDEpICsKICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cyA9IGMoIk1hbnVhbCBBbm5vdGF0aW9uIiwgIlNpbmdsZVIgQW5ub3RhdGlvbiIpLAogICAgICAgICAgICAgICAgICAgZXhwYW5kID0gYyguMSwgLjEpKSArCiAgbGFicyh5ID0gIkxvZzEwIFtDbHVzdGVyIHNpemVdIikgKwogIHRoZW1lX21pbmltYWwoKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyNSksIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTApKSsKICBzY2FsZV9maWxsX2dyYWRpZW50MihtaWRwb2ludCA9IDAsIGxvdz0icmVkIiwgbWlkPSJvcmFuZ2UiLCBoaWdoPSJ5ZWxsb3ciLCBuYW1lID0gImxvZzEwW0NlbGxzXSIpCgoKZ2dwbG90KHNsaWNlX2RmMSwKICAgICAgIGFlcyhheGlzMSA9IHN1YmNsdXN0ZXJfbmFtZSwKICAgICAgICAgICBheGlzMiA9IGxhYmVscywKICAgICAgICAgICB5ID0gbG9nZnJlcSkpICsKICBnZW9tX2FsbHV2aXVtKGFlcyhmaWxsID0gbG9nRnJlcXVlbmN5bWF0Y2gpKSsKICBnZW9tX3N0cmF0dW0oKSArCiAgZ2VvbV9sYWJlbChzdGF0ID0gInN0cmF0dW0iLCBhZXMobGFiZWwgPSBhZnRlcl9zdGF0KHN0cmF0dW0pKSwgbGFiZWwuc2l6ZSA9IDAuMDEpICsKICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cyA9IGMoIk1hbnVhbCBBbm5vdGF0aW9uIiwgIlNpbmdsZVIgQW5ub3RhdGlvbiIpLAogICAgICAgICAgICAgICAgICAgZXhwYW5kID0gYyguMSwgLjEpKSArCiAgbGFicyh5ID0gIkxvZzEwIFtDbHVzdGVyIHNpemVdIikgKwogIHRoZW1lX21pbmltYWwoKSsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyNSksIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTApKSsKICBzY2FsZV9maWxsX2dyYWRpZW50MihtaWRwb2ludCA9IDEsIGxvdz0icmVkIiwgbWlkPSJvcmFuZ2UiLCBoaWdoPSJ5ZWxsb3ciLCBuYW1lID0gImxvZzEwW0NlbGxzXSIpCgpgYGAKCmBgYHtyfQpteWVsb2lkIDwtIHNsaWNlWyxzbGljZSRjbHVzdGVyX25hbWUgPT0gIk15ZWxvaWRfY2VsbHMiXQoKc2xpY2VfZGYgPC0gYXMuZGF0YS5mcmFtZShjb2xEYXRhKG15ZWxvaWQpKQpzbGljZV9kZiA8LSBzbGljZV9kZlssYygibGFiZWxzIiwgInN1YmNsdXN0ZXJfbmFtZSIpXQpzbGljZV9kZjEgPC0gc2xpY2VfZGYgJT4lIGdyb3VwX2J5KHN1YmNsdXN0ZXJfbmFtZSwgbGFiZWxzKSAlPiUgc3VtbWFyaXNlKEZyZXF1ZW5jeSA9IG4oKSkKc2xpY2VfZGYxJHN1YmNsdXN0ZXJfbmFtZVtzbGljZV9kZjEkc3ViY2x1c3Rlcl9uYW1lID09ICJDRDE0K19Nb25vY3l0ZXMiXSA8LSAiQ0QxNCtfbW9ub2N5dGVzIgpzbGljZV9kZjEkTWF0Y2ggPC0gaWZlbHNlKHNsaWNlX2RmMSRzdWJjbHVzdGVyX25hbWUgPT0gc2xpY2VfZGYxJGxhYmVscywgIlllcyIsICJObyIpCnNsaWNlX2RmMSA8LSBzbGljZV9kZjFbc2xpY2VfZGYxJEZyZXF1ZW5jeSA+PSAxMCwgXQpzbGljZV9kZjEkbG9nZnJlcSA8LSBsb2cxMChzbGljZV9kZjEkRnJlcXVlbmN5KQpzbGljZV9kZjEkRnJlcXVlbmN5bWF0Y2ggPC0gaWZlbHNlKHNsaWNlX2RmMSRNYXRjaCA9PSAiWWVzIiwgc2xpY2VfZGYxJEZyZXF1ZW5jeSwgMC1zbGljZV9kZjEkRnJlcXVlbmN5KQpzbGljZV9kZjEkbG9nRnJlcXVlbmN5bWF0Y2ggPC0gaWZlbHNlKHNsaWNlX2RmMSRNYXRjaCA9PSAiWWVzIiwgc2xpY2VfZGYxJGxvZ2ZyZXEsIDAtc2xpY2VfZGYxJGxvZ2ZyZXEpCgoKCgpnZ3Bsb3Qoc2xpY2VfZGYxLAogICAgICAgYWVzKGF4aXMxID0gc3ViY2x1c3Rlcl9uYW1lLAogICAgICAgICAgIGF4aXMyID0gbGFiZWxzLAogICAgICAgICAgIHkgPSBsb2dmcmVxKSkgKwogICAgZ2VvbV9hbGx1dml1bShhZXMoYWxwaGEgPSBGcmVxdWVuY3kpKSArCiAgZ2VvbV9hbGx1dml1bShhZXMoZmlsbCA9IE1hdGNoKSkgKyAKICBnZW9tX3N0cmF0dW0oKSArCiAgZ2VvbV9sYWJlbChzdGF0ID0gInN0cmF0dW0iLCBhZXMobGFiZWwgPSBhZnRlcl9zdGF0KHN0cmF0dW0pKSwgbGFiZWwuc2l6ZSA9IDAuMDEpICsKICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cyA9IGMoIk1hbnVhbCBBbm5vdGF0aW9uIiwgIlNpbmdsZVIgQW5ub3RhdGlvbiIpLAogICAgICAgICAgICAgICAgICAgZXhwYW5kID0gYyguMSwgLjEpKSArCiAgbGFicyh5ID0gIkxvZzEwIFtDbHVzdGVyIHNpemVdIiwgYWxwaGEgPSAiTnVtYmVyIG9mIENlbGxzIiwgZmlsbCA9ICJBbm5vdGF0aW9ucyBtYXRjaD8iKSArCiAgdGhlbWVfbWluaW1hbCgpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDI1KSwgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMCkpCgpnZ3Bsb3Qoc2xpY2VfZGYxLAogICAgICAgYWVzKGF4aXMxID0gc3ViY2x1c3Rlcl9uYW1lLAogICAgICAgICAgIGF4aXMyID0gbGFiZWxzLAogICAgICAgICAgIHkgPSBsb2dmcmVxKSkgKwogIGdlb21fYWxsdXZpdW0oYWVzKGZpbGwgPSBGcmVxdWVuY3ltYXRjaCkpKwogIGdlb21fc3RyYXR1bSgpICsKICBnZW9tX2xhYmVsKHN0YXQgPSAic3RyYXR1bSIsIGFlcyhsYWJlbCA9IGFmdGVyX3N0YXQoc3RyYXR1bSkpLCBsYWJlbC5zaXplID0gMC4wMSkgKwogIHNjYWxlX3hfZGlzY3JldGUobGltaXRzID0gYygiTWFudWFsIEFubm90YXRpb24iLCAiU2luZ2xlUiBBbm5vdGF0aW9uIiksCiAgICAgICAgICAgICAgICAgICBleHBhbmQgPSBjKC4xLCAuMSkpICsKICBsYWJzKHkgPSAiTG9nMTAgW0NsdXN0ZXIgc2l6ZV0iKSArCiAgdGhlbWVfbWluaW1hbCgpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDI1KSwgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMCkpKwogIHNjYWxlX2ZpbGxfZ3JhZGllbnQyKG1pZHBvaW50ID0gMCwgbG93PSJyZWQiLCBtaWQ9Im9yYW5nZSIsIGhpZ2g9InllbGxvdyIsIG5hbWUgPSAibG9nMTBbQ2VsbHNdIikKCgpnZ3Bsb3Qoc2xpY2VfZGYxLAogICAgICAgYWVzKGF4aXMxID0gc3ViY2x1c3Rlcl9uYW1lLAogICAgICAgICAgIGF4aXMyID0gbGFiZWxzLAogICAgICAgICAgIHkgPSBsb2dmcmVxKSkgKwogIGdlb21fYWxsdXZpdW0oYWVzKGZpbGwgPSBsb2dGcmVxdWVuY3ltYXRjaCkpKwogIGdlb21fc3RyYXR1bSgpICsKICBnZW9tX2xhYmVsKHN0YXQgPSAic3RyYXR1bSIsIGFlcyhsYWJlbCA9IGFmdGVyX3N0YXQoc3RyYXR1bSkpLCBsYWJlbC5zaXplID0gMC4wMSkgKwogIHNjYWxlX3hfZGlzY3JldGUobGltaXRzID0gYygiTWFudWFsIEFubm90YXRpb24iLCAiU2luZ2xlUiBBbm5vdGF0aW9uIiksCiAgICAgICAgICAgICAgICAgICBleHBhbmQgPSBjKC4xLCAuMSkpICsKICBsYWJzKHkgPSAiTG9nMTAgW0NsdXN0ZXIgc2l6ZV0iKSArCiAgdGhlbWVfbWluaW1hbCgpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDI1KSwgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMCkpKwogIHNjYWxlX2ZpbGxfZ3JhZGllbnQyKG1pZHBvaW50ID0gMSwgbG93PSJyZWQiLCBtaWQ9Im9yYW5nZSIsIGhpZ2g9InllbGxvdyIsIG5hbWUgPSAibG9nMTBbQ2VsbHNdIikKCmBgYAoKCgoKYGBge3J9Cmx5bXBob2lkIDwtIHNsaWNlWyxzbGljZSRjbHVzdGVyX25hbWUgPT0gIkx5bXBob2lkX2NlbGxzIl0KCnNsaWNlX2RmIDwtIGFzLmRhdGEuZnJhbWUoY29sRGF0YShseW1waG9pZCkpCnNsaWNlX2RmIDwtIHNsaWNlX2RmWyxjKCJsYWJlbHMiLCAic3ViY2x1c3Rlcl9uYW1lIildCnNsaWNlX2RmMSA8LSBzbGljZV9kZiAlPiUgZ3JvdXBfYnkoc3ViY2x1c3Rlcl9uYW1lLCBsYWJlbHMpICU+JSBzdW1tYXJpc2UoRnJlcXVlbmN5ID0gbigpKQpzbGljZV9kZjEkTWF0Y2ggPC0gaWZlbHNlKHNsaWNlX2RmMSRzdWJjbHVzdGVyX25hbWUgPT0gc2xpY2VfZGYxJGxhYmVscywgIlllcyIsICJObyIpCnNsaWNlX2RmMSA8LSBzbGljZV9kZjFbc2xpY2VfZGYxJEZyZXF1ZW5jeSA+PSAxMCwgXQpzbGljZV9kZjEkbG9nZnJlcSA8LSBsb2cxMChzbGljZV9kZjEkRnJlcXVlbmN5KQpzbGljZV9kZjEkRnJlcXVlbmN5bWF0Y2ggPC0gaWZlbHNlKHNsaWNlX2RmMSRNYXRjaCA9PSAiWWVzIiwgc2xpY2VfZGYxJEZyZXF1ZW5jeSwgMC1zbGljZV9kZjEkRnJlcXVlbmN5KQpzbGljZV9kZjEkbG9nRnJlcXVlbmN5bWF0Y2ggPC0gaWZlbHNlKHNsaWNlX2RmMSRNYXRjaCA9PSAiWWVzIiwgc2xpY2VfZGYxJGxvZ2ZyZXEsIDAtc2xpY2VfZGYxJGxvZ2ZyZXEpCgpnZ3Bsb3Qoc2xpY2VfZGYxLAogICAgICAgYWVzKGF4aXMxID0gc3ViY2x1c3Rlcl9uYW1lLAogICAgICAgICAgIGF4aXMyID0gbGFiZWxzLAogICAgICAgICAgIHkgPSBsb2dmcmVxKSkgKwogICAgZ2VvbV9hbGx1dml1bShhZXMoYWxwaGEgPSBGcmVxdWVuY3kpKSArCiAgZ2VvbV9hbGx1dml1bShhZXMoZmlsbCA9IE1hdGNoKSkgKyAKICBnZW9tX3N0cmF0dW0oKSArCiAgZ2VvbV9sYWJlbChzdGF0ID0gInN0cmF0dW0iLCBhZXMobGFiZWwgPSBhZnRlcl9zdGF0KHN0cmF0dW0pKSwgbGFiZWwuc2l6ZSA9IDAuMDEpICsKICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cyA9IGMoIk1hbnVhbCBBbm5vdGF0aW9uIiwgIlNpbmdsZVIgQW5ub3RhdGlvbiIpLAogICAgICAgICAgICAgICAgICAgZXhwYW5kID0gYyguMSwgLjEpKSArCiAgbGFicyh5ID0gIkxvZzEwIFtDbHVzdGVyIHNpemVdIiwgYWxwaGEgPSAiTnVtYmVyIG9mIENlbGxzIiwgZmlsbCA9ICJBbm5vdGF0aW9ucyBtYXRjaD8iKSArCiAgdGhlbWVfbWluaW1hbCgpKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDI1KSwgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMCkpICAgICAgICAgICAgICAgIAoKCmdncGxvdChzbGljZV9kZjEsCiAgICAgICBhZXMoYXhpczEgPSBzdWJjbHVzdGVyX25hbWUsCiAgICAgICAgICAgYXhpczIgPSBsYWJlbHMsCiAgICAgICAgICAgeSA9IGxvZ2ZyZXEpKSArCiAgZ2VvbV9hbGx1dml1bShhZXMoZmlsbCA9IEZyZXF1ZW5jeW1hdGNoKSkrCiAgZ2VvbV9zdHJhdHVtKCkgKwogIGdlb21fbGFiZWwoc3RhdCA9ICJzdHJhdHVtIiwgYWVzKGxhYmVsID0gYWZ0ZXJfc3RhdChzdHJhdHVtKSksIGxhYmVsLnNpemUgPSAwLjAxKSArCiAgc2NhbGVfeF9kaXNjcmV0ZShsaW1pdHMgPSBjKCJNYW51YWwgQW5ub3RhdGlvbiIsICJTaW5nbGVSIEFubm90YXRpb24iKSwKICAgICAgICAgICAgICAgICAgIGV4cGFuZCA9IGMoLjEsIC4xKSkgKwogIGxhYnMoeSA9ICJMb2cxMCBbQ2x1c3RlciBzaXplXSIpICsKICB0aGVtZV9taW5pbWFsKCkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMjUpLCBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEwKSkrCiAgc2NhbGVfZmlsbF9ncmFkaWVudDIobWlkcG9pbnQgPSAwLCBsb3c9InJlZCIsIG1pZD0ib3JhbmdlIiwgaGlnaD0ieWVsbG93IiwgbmFtZSA9ICJsb2cxMFtDZWxsc10iKQoKCmdncGxvdChzbGljZV9kZjEsCiAgICAgICBhZXMoYXhpczEgPSBzdWJjbHVzdGVyX25hbWUsCiAgICAgICAgICAgYXhpczIgPSBsYWJlbHMsCiAgICAgICAgICAgeSA9IGxvZ2ZyZXEpKSArCiAgZ2VvbV9hbGx1dml1bShhZXMoZmlsbCA9IGxvZ0ZyZXF1ZW5jeW1hdGNoKSkrCiAgZ2VvbV9zdHJhdHVtKCkgKwogIGdlb21fbGFiZWwoc3RhdCA9ICJzdHJhdHVtIiwgYWVzKGxhYmVsID0gYWZ0ZXJfc3RhdChzdHJhdHVtKSksIGxhYmVsLnNpemUgPSAwLjAxKSArCiAgc2NhbGVfeF9kaXNjcmV0ZShsaW1pdHMgPSBjKCJNYW51YWwgQW5ub3RhdGlvbiIsICJTaW5nbGVSIEFubm90YXRpb24iKSwKICAgICAgICAgICAgICAgICAgIGV4cGFuZCA9IGMoLjEsIC4xKSkgKwogIGxhYnMoeSA9ICJMb2cxMCBbQ2x1c3RlciBzaXplXSIpICsKICB0aGVtZV9taW5pbWFsKCkrCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMjUpLCBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEwKSkrCiAgc2NhbGVfZmlsbF9ncmFkaWVudDIobWlkcG9pbnQgPSAxLCBsb3c9InJlZCIsIG1pZD0ib3JhbmdlIiwgaGlnaD0ieWVsbG93IiwgbmFtZSA9ICJsb2cxMFtDZWxsc10iKQoKYGBgCgoKCiMjIyBEaWZmZXJlbnRpYWwgQWJ1bmRhbmNlCgoKYGBge3J9Cndob2xlX2RhIDwtIHdob2xlWyx3aG9sZSRjbHVzdGVyX25hbWUgJWluJSBjKCJGaWJyb2JsYXN0cyIsICJFbmRvdGhlbGlhbF9jZWxscyIsICJNeWVsb2lkX2NlbGxzIiwgIlBlcmljeXRlcyIpXQpzbGljZV9kYSA8LSBzbGljZVssc2xpY2UkY2x1c3Rlcl9uYW1lICVpbiUgYygiRmlicm9ibGFzdHMiLCAiRW5kb3RoZWxpYWxfY2VsbHMiLCAiTXllbG9pZF9jZWxscyIsICJQZXJpY3l0ZXMiKV0KCndob2xlX2RhIDwtIGNvbERhdGEod2hvbGVfZGEpCnNsaWNlX2RhIDwtIGNvbERhdGEoc2xpY2VfZGEpCgp3aG9sZV9kYSA8LSB3aG9sZV9kYVt3aG9sZV9kYSRkb25vcl9pZCAlaW4lIGMoIlByTE40IiwgIlByTE41IiwgIlByTE42IiksIF0Kc2xpY2VfZGEgPC0gc2xpY2VfZGFbc2xpY2VfZGEkc2FtcGxlX2lkICVpbiUgYygiUHJMTjRfc0NUUkwiLCAiUHJMTjVfc0NUUkwiLCAiUHJMTjZfc0NUUkwiKSxdCgp3aG9sZV9kYSRzYW1wbGVfaWQgPC0gZHJvcGxldmVscyh3aG9sZV9kYSRzYW1wbGVfaWQpCndob2xlX2RhJHNhbXBsZV90eXBlIDwtIGRyb3BsZXZlbHMod2hvbGVfZGEkc2FtcGxlX3R5cGUpCndob2xlX2RhJGRvbm9yX2lkIDwtIGRyb3BsZXZlbHMod2hvbGVfZGEkZG9ub3JfaWQpCgpzbGljZV9kYSRzYW1wbGVfaWQgPC0gZHJvcGxldmVscyhzbGljZV9kYSRzYW1wbGVfaWQpCnNsaWNlX2RhJHNhbXBsZV90eXBlIDwtIGRyb3BsZXZlbHMoc2xpY2VfZGEkc2FtcGxlX3R5cGUpCgp0YWJsZSh3aG9sZV9kYSRkb25vcl9pZCkKdGFibGUoc2xpY2VfZGEkc2FtcGxlX2lkKQp0YWJsZSh3aG9sZV9kYSRzYW1wbGVfdHlwZSkKdGFibGUod2hvbGVfZGEkc2FtcGxlX2lkKQp0YWJsZShzbGljZV9kYSRzYW1wbGVfdHlwZSkKYGBgCgpgYGB7cn0KZGlmZl9hYnVuZGFuY2VfdyA8LSBhcy5kYXRhLmZyYW1lKHRhYmxlKHdob2xlX2RhJHNhbXBsZV9pZCwgd2hvbGVfZGEkc3ViY2x1c3Rlcl9uYW1lKSkKZGlmZl9hYnVuZGFuY2VfcyA8LSBhcy5kYXRhLmZyYW1lKHRhYmxlKHNsaWNlX2RhJHNhbXBsZV9pZCwgc2xpY2VfZGEkc3ViY2x1c3Rlcl9uYW1lKSkKZGlmZl9hYnVuZGFuY2UgPC0gcmJpbmQoZGlmZl9hYnVuZGFuY2VfdywgZGlmZl9hYnVuZGFuY2VfcykKCgpjb2xuYW1lcyhkaWZmX2FidW5kYW5jZSkgPC0gYygic2FtcGxlX2lkIiwgImNlbGxfdHlwZSIsICJudW1iZXJfb2ZfY2VsbHMiKQpkaWZmX2FidW5kYW5jZSA8LSBzZXBhcmF0ZShkYXRhID0gZGlmZl9hYnVuZGFuY2UsIGNvbCA9ICJzYW1wbGVfaWQiLCBjKCdkb25vcl9pZCcsICdzYW1wbGVfdHlwZScpLCBzZXAgPSAiXyIsIHJlbW92ZSA9IEZBTFNFKQpkaWZmX2FidW5kYW5jZSRkb25vcl9pZCA8LSBhcy5mYWN0b3IoZGlmZl9hYnVuZGFuY2UkZG9ub3JfaWQpCmRpZmZfYWJ1bmRhbmNlJHNhbXBsZV9pZCA8LSBhcy5mYWN0b3IoZGlmZl9hYnVuZGFuY2Ukc2FtcGxlX2lkKQpkaWZmX2FidW5kYW5jZSRzYW1wbGVfdHlwZSA8LSBhcy5mYWN0b3IoZGlmZl9hYnVuZGFuY2Ukc2FtcGxlX3R5cGUpCmRpZmZfYWJ1bmRhbmNlCmBgYAoKdG8gY2FsY3VsYXRlIHRoZSBwZXJjZW50YWdlIHdlIGRpdmlkZSBieSB0aGUgdG90YWwgbnVtYmVyIG9mIGNlbGxzIGluIHRoZSBzYW1wbGUKCmBgYHtyfQpjZWxsc19wZXJfc2FtcGxlIDwtIHJiaW5kKGRhdGEuZnJhbWUodGFibGUoc2xpY2VfZGEkc2FtcGxlX2lkKSksIGRhdGEuZnJhbWUodGFibGUod2hvbGVfZGEkc2FtcGxlX2lkKSkpCmNvbG5hbWVzKGNlbGxzX3Blcl9zYW1wbGUpIDwtIGMoInNhbXBsZV9pZCIsICJjZWxsc19wZXJfc2FtcGxlIikKY2VsbHNfcGVyX3NhbXBsZQptYXRjaGluZ19yb3dzIDwtIG1hdGNoKGRpZmZfYWJ1bmRhbmNlJHNhbXBsZV9pZCwgY2VsbHNfcGVyX3NhbXBsZSRzYW1wbGVfaWQpCmRpZmZfYWJ1bmRhbmNlJGNlbGxzX3Blcl9zYW1wbGUgPC0gY2VsbHNfcGVyX3NhbXBsZSRjZWxsc19wZXJfc2FtcGxlW21hdGNoaW5nX3Jvd3NdCmRpZmZfYWJ1bmRhbmNlCmBgYAoKYGBge3J9CmRpZmZfYWJ1bmRhbmNlJHBlcmNlbnRhZ2VfY2VsbHMgPC0gZGlmZl9hYnVuZGFuY2UkbnVtYmVyX29mX2NlbGxzL2RpZmZfYWJ1bmRhbmNlJGNlbGxzX3Blcl9zYW1wbGUKZGlmZl9hYnVuZGFuY2UKYGBgCgpgYGB7cn0KZGlmZl9hYnVuZGFuY2UgPC0gZGlmZl9hYnVuZGFuY2UgJT4lIAogIG11dGF0ZShjYXRlZ29yeSA9IHJlY29kZShjZWxsX3R5cGUsICJDRDE0K19Nb25vY3l0ZXMiID0gIkNEMTQrX21vbm9jeXRlcyIpKQoKZGlmZl9hYnVuZGFuY2UkY2VsbF90eXBlW2RpZmZfYWJ1bmRhbmNlJGNlbGxfdHlwZSA9PSAiQ0QxNCtfTW9ub2N5dGVzIl0gPC0gIkNEMTQrX21vbm9jeXRlcyIKYGBgCgoKYGBge3IgZmlnLndpZHRoPTE2fQoKCmdncGxvdChkaWZmX2FidW5kYW5jZSwgYWVzKHggPSBmYWN0b3IoY2VsbF90eXBlLCBsZXZlbCA9IGMoIkNEMTQrX21vbm9jeXRlcyIsICJDRDE2K19tb25vY3l0ZXMiLCAiTmV1dHJvcGhpbHMiLCAiTWFzdF9jZWxscyIsICJDRDFDK19EQ3MiLCAiQ0xFQzlBaGlnaF9EQ3MiLCAiWENSMStfQ0xFQzlBaGlnaF9EQ3MiLCAiWENSMStfRENzIiwgIkxBTVAzK19EQ3MiLCAiTEFNUDMrX0NDTDE3aGlnaF9EQ3MiLCAicERDcyIsICJtaXRvX2hpZ2hfbXllbG9pZCIsICJQRUNBTTFoaWdoX0NBVjFoaWdoX0VTQU1oaWdoX0xFQyIsICJQRUNBTTFoaWdoX05UNUUrX0xFQyIsICJQRUNBTTFsb3dfQ0NMMjBoaWdoX0xFQyIsICJQRUNBTTFoaWdoX0NBVjFoaWdoX0xFQyIsICJQRUNBTTFsb3dfRUZOQjJoaWdoX0xFQyIsIkxZVkUxK19MRUMiLCAiQ0NMMTloaWdoX0ZpYnJvYmxhc3RzIiwgIkNYQ0wxMmhpZ2hfRmlicm9ibGFzdHMiLCAiQ1hDTDEyaGlnaF9IREFDMTErX0ZpYnJvYmxhc3RzIiwiUEkxNitfRmlicm9ibGFzdHMiLCAiUFRQUkdoaWdoX0ZpYnJvYmxhc3RzIiwgIlBlcmljeXRlcyIsICJJVEdBMWhpZ2hfWkVCMmhpZ2hfUGVyaWN5dGVzIiwiSERBQzExK19jeWNsaW5nX1BlcmljeXRlcyIsICJQRUFSMStfUGVyaWN5dGVzIiwgIk15b2ZpYnJvYmxhc3RzIikpLCB5ID0gcGVyY2VudGFnZV9jZWxscywgZmlsbCA9IHNhbXBsZV90eXBlKSkgKwogIGdlb21fYm94cGxvdCgpICsgCiAgbGFicyh4ID0gIkNlbGwgVHlwZSIsIHkgPSAiUHJvcG9ydGlvbiBvZiBjZWxscyAoYXZlcmFnZSBhY3Jvc3MgZG9ub3JzKSIsIGZpbGwgPSAiVHJlYXRtZW50IikgKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA1NSwgaGp1c3QgPSAxKSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCIjRTc4QUMzIiwgIiNBMUQ5OUIiKSkKCmdncGxvdChkaWZmX2FidW5kYW5jZSwgYWVzKHggPSBmYWN0b3IoY2VsbF90eXBlLCBsZXZlbCA9IGMoIkNEMTQrX21vbm9jeXRlcyIsICJDRDE2K19tb25vY3l0ZXMiLCAiTmV1dHJvcGhpbHMiLCAiTWFzdF9jZWxscyIsICJDRDFDK19EQ3MiLCAiQ0xFQzlBaGlnaF9EQ3MiLCAiWENSMStfQ0xFQzlBaGlnaF9EQ3MiLCAiWENSMStfRENzIiwgIkxBTVAzK19EQ3MiLCAiTEFNUDMrX0NDTDE3aGlnaF9EQ3MiLCAicERDcyIsICJtaXRvX2hpZ2hfbXllbG9pZCIsICJQRUNBTTFoaWdoX0NBVjFoaWdoX0VTQU1oaWdoX0xFQyIsICJQRUNBTTFoaWdoX05UNUUrX0xFQyIsICJQRUNBTTFsb3dfQ0NMMjBoaWdoX0xFQyIsICJQRUNBTTFoaWdoX0NBVjFoaWdoX0xFQyIsICJQRUNBTTFsb3dfRUZOQjJoaWdoX0xFQyIsIkxZVkUxK19MRUMiLCAiQ0NMMTloaWdoX0ZpYnJvYmxhc3RzIiwgIkNYQ0wxMmhpZ2hfRmlicm9ibGFzdHMiLCAiQ1hDTDEyaGlnaF9IREFDMTErX0ZpYnJvYmxhc3RzIiwiUEkxNitfRmlicm9ibGFzdHMiLCAiUFRQUkdoaWdoX0ZpYnJvYmxhc3RzIiwgIlBlcmljeXRlcyIsICJJVEdBMWhpZ2hfWkVCMmhpZ2hfUGVyaWN5dGVzIiwiSERBQzExK19jeWNsaW5nX1BlcmljeXRlcyIsICJQRUFSMStfUGVyaWN5dGVzIiwgIk15b2ZpYnJvYmxhc3RzIikpLCB5ID0gcGVyY2VudGFnZV9jZWxscywgZmlsbCA9IHNhbXBsZV90eXBlKSkgKwogIGdlb21fYm94cGxvdCgpICsgCiAgbGFicyh4ID0gIkNlbGwgVHlwZSIsIHkgPSAiUHJvcG9ydGlvbiBvZiBjZWxscyAoYXZlcmFnZSBhY3Jvc3MgZG9ub3JzKSIsIGZpbGwgPSAiU2FtcGxlIFR5cGUiLCBjb2wgPSAiU2FtcGxlIElEIikgKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA1NSwgaGp1c3QgPSAxKSxwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAid2hpdGUiLCBjb2xvdXIgPSJkYXJrZ3JheSIsIHNpemUgPSAyKSwgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiZ3JheSIsIHNpemUgPSAwLjMpKSsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygiI0U3OEFDMyIsICIjQTFEOTlCIikpKwogIGdlb21fcG9pbnQoYWVzKGNvbCA9IHNhbXBsZV9pZCksIHNpemUgPSAyKQoKICAKYGBgCgpgYGB7cn0KZGlmZl9hYnVuZGFuY2UxID0gZGlmZl9hYnVuZGFuY2VbZGlmZl9hYnVuZGFuY2UkY2VsbF90eXBlICVpbiUgYygiQ0QxNCtfbW9ub2N5dGVzIiwgIk5ldXRyb3BoaWxzIiwgIk1hc3RfY2VsbHMiLCAiTEFNUDMrX0RDcyIsICJwRENzIiwgIkNDTDE5aGlnaF9GaWJyb2JsYXN0cyIsICJDWENMMTJoaWdoX0ZpYnJvYmxhc3RzIiwiUEkxNitfRmlicm9ibGFzdHMiLCAiUFRQUkdoaWdoX0ZpYnJvYmxhc3RzIiwgIlBlcmljeXRlcyIsICJNeW9maWJyb2JsYXN0cyIpLF0KCmNkMTkubW9kZWwgPC0gbG0ocGVyY2VudGFnZV9jZWxscyB+IGNlbGxfdHlwZSArIHNhbXBsZV90eXBlLCBkYXRhID0gZGlmZl9hYnVuZGFuY2UxKQp0ZW1wIDwtIGRpZmZfYWJ1bmRhbmNlMSAlPiUKICBncm91cF9ieShjZWxsX3R5cGUpICU+JQogIGFub3ZhX3Rlc3QocGVyY2VudGFnZV9jZWxscyB+IHNhbXBsZV90eXBlLCBlcnJvciA9IGNkMTkubW9kZWwpCgp0ZW1wCgpjZDE5Lm1vZGVsIDwtIGxtKHBlcmNlbnRhZ2VfY2VsbHMgfiBjZWxsX3R5cGUqc2FtcGxlX3R5cGUsIGRhdGEgPSBkaWZmX2FidW5kYW5jZTEpCnRlbXAxIDwtIGRpZmZfYWJ1bmRhbmNlMSAlPiUKICBncm91cF9ieShjZWxsX3R5cGUpICU+JQogIGFub3ZhX3Rlc3QocGVyY2VudGFnZV9jZWxscyB+IHNhbXBsZV90eXBlLCBlcnJvciA9IGNkMTkubW9kZWwpCgp0ZW1wMQoKCnB3YyA8LSBkaWZmX2FidW5kYW5jZTEgJT4lIAogIGdyb3VwX2J5KGNlbGxfdHlwZSkgJT4lCiAgZW1tZWFuc190ZXN0KHBlcmNlbnRhZ2VfY2VsbHMgfiBzYW1wbGVfdHlwZSwgcC5hZGp1c3QubWV0aG9kID0gImJvbmZlcnJvbmkiKSAKcHdjCiAKcHdjMSA8LSBzdWJzZXQocHdjLCBzZWxlY3QgPSBjKGNlbGxfdHlwZSwgc3RhdGlzdGljLCBwKSkKcHdjMSA8LSBwd2MxW29yZGVyKHB3YzEkcCksXQpjb2xuYW1lcyhwd2MxKSA8LSBjKCJjZWxsX3R5cGUiLCAic3RhdGlzdGljIiwgInBfdmFsdWUiKQpwd2MxCmBgYAoKCmBgYHtyfQpkaWZmX2FidW5kYW5jZV93IDwtIGFzLmRhdGEuZnJhbWUodGFibGUod2hvbGVfZGEkc2FtcGxlX2lkLCB3aG9sZV9kYSRjbHVzdGVyX25hbWUpKQpkaWZmX2FidW5kYW5jZV9zIDwtIGFzLmRhdGEuZnJhbWUodGFibGUoc2xpY2VfZGEkc2FtcGxlX2lkLCBzbGljZV9kYSRjbHVzdGVyX25hbWUpKQpkaWZmX2FidW5kYW5jZSA8LSByYmluZChkaWZmX2FidW5kYW5jZV93LCBkaWZmX2FidW5kYW5jZV9zKQoKCmNvbG5hbWVzKGRpZmZfYWJ1bmRhbmNlKSA8LSBjKCJzYW1wbGVfaWQiLCAiY2VsbF90eXBlIiwgIm51bWJlcl9vZl9jZWxscyIpCmRpZmZfYWJ1bmRhbmNlIDwtIHNlcGFyYXRlKGRhdGEgPSBkaWZmX2FidW5kYW5jZSwgY29sID0gInNhbXBsZV9pZCIsIGMoJ2Rvbm9yX2lkJywgJ3NhbXBsZV90eXBlJyksIHNlcCA9ICJfIiwgcmVtb3ZlID0gRkFMU0UpCmRpZmZfYWJ1bmRhbmNlJGRvbm9yX2lkIDwtIGFzLmZhY3RvcihkaWZmX2FidW5kYW5jZSRkb25vcl9pZCkKZGlmZl9hYnVuZGFuY2Ukc2FtcGxlX2lkIDwtIGFzLmZhY3RvcihkaWZmX2FidW5kYW5jZSRzYW1wbGVfaWQpCmRpZmZfYWJ1bmRhbmNlJHNhbXBsZV90eXBlIDwtIGFzLmZhY3RvcihkaWZmX2FidW5kYW5jZSRzYW1wbGVfdHlwZSkKZGlmZl9hYnVuZGFuY2UKYGBgCgp0byBjYWxjdWxhdGUgdGhlIHBlcmNlbnRhZ2Ugd2UgZGl2aWRlIGJ5IHRoZSB0b3RhbCBudW1iZXIgb2YgY2VsbHMgaW4gdGhlIHNhbXBsZQoKYGBge3J9CmNlbGxzX3Blcl9zYW1wbGUgPC0gcmJpbmQoZGF0YS5mcmFtZSh0YWJsZShzbGljZV9kYSRzYW1wbGVfaWQpKSwgZGF0YS5mcmFtZSh0YWJsZSh3aG9sZV9kYSRzYW1wbGVfaWQpKSkKY29sbmFtZXMoY2VsbHNfcGVyX3NhbXBsZSkgPC0gYygic2FtcGxlX2lkIiwgImNlbGxzX3Blcl9zYW1wbGUiKQpjZWxsc19wZXJfc2FtcGxlCm1hdGNoaW5nX3Jvd3MgPC0gbWF0Y2goZGlmZl9hYnVuZGFuY2Ukc2FtcGxlX2lkLCBjZWxsc19wZXJfc2FtcGxlJHNhbXBsZV9pZCkKZGlmZl9hYnVuZGFuY2UkY2VsbHNfcGVyX3NhbXBsZSA8LSBjZWxsc19wZXJfc2FtcGxlJGNlbGxzX3Blcl9zYW1wbGVbbWF0Y2hpbmdfcm93c10KZGlmZl9hYnVuZGFuY2UKYGBgCgpgYGB7cn0KZGlmZl9hYnVuZGFuY2UkcGVyY2VudGFnZV9jZWxscyA8LSBkaWZmX2FidW5kYW5jZSRudW1iZXJfb2ZfY2VsbHMvZGlmZl9hYnVuZGFuY2UkY2VsbHNfcGVyX3NhbXBsZQpkaWZmX2FidW5kYW5jZQoKYGBgCgpgYGB7cn0KY2QxOS5tb2RlbCA8LSBsbShwZXJjZW50YWdlX2NlbGxzIH4gY2VsbF90eXBlICsgc2FtcGxlX3R5cGUsIGRhdGEgPSBkaWZmX2FidW5kYW5jZSkKdGVtcCA8LSBkaWZmX2FidW5kYW5jZSAlPiUKICBncm91cF9ieShjZWxsX3R5cGUpICU+JQogIGFub3ZhX3Rlc3QocGVyY2VudGFnZV9jZWxscyB+IHNhbXBsZV90eXBlLCBlcnJvciA9IGNkMTkubW9kZWwpCgp0ZW1wCgpjZDE5Lm1vZGVsIDwtIGxtKHBlcmNlbnRhZ2VfY2VsbHMgfiBjZWxsX3R5cGUqc2FtcGxlX3R5cGUsIGRhdGEgPSBkaWZmX2FidW5kYW5jZSkKdGVtcDEgPC0gZGlmZl9hYnVuZGFuY2UgJT4lCiAgZ3JvdXBfYnkoY2VsbF90eXBlKSAlPiUKICBhbm92YV90ZXN0KHBlcmNlbnRhZ2VfY2VsbHMgfiBzYW1wbGVfdHlwZSwgZXJyb3IgPSBjZDE5Lm1vZGVsKQoKdGVtcDEKCgpwd2MgPC0gZGlmZl9hYnVuZGFuY2UgJT4lIAogIGdyb3VwX2J5KGNlbGxfdHlwZSkgJT4lCiAgZW1tZWFuc190ZXN0KHBlcmNlbnRhZ2VfY2VsbHMgfiBzYW1wbGVfdHlwZSwgcC5hZGp1c3QubWV0aG9kID0gImJvbmZlcnJvbmkiKSAKcHdjCiAKCmBgYAoKYGBge3J9CgoKZ2dwbG90KGRpZmZfYWJ1bmRhbmNlLCBhZXMoeCA9IGNlbGxfdHlwZSwgeSA9IHBlcmNlbnRhZ2VfY2VsbHMsIGZpbGwgPSBzYW1wbGVfdHlwZSkpICsKICBnZW9tX2JveHBsb3QoKSArIAogIGxhYnMoeCA9ICJDZWxsIFR5cGUiLCB5ID0gIlByb3BvcnRpb24gb2YgY2VsbHMgKGF2ZXJhZ2UgYWNyb3NzIGRvbm9ycykiLCBmaWxsID0gIlRyZWF0bWVudCIsIGNvbCA9ICJTYW1wbGUgSUQiKSArCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLCBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDU1LCBoanVzdCA9IDEpKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoIiNFNzhBQzMiLCAiI0ExRDk5QiIpKSsKICBnZW9tX3BvaW50KGFlcyhjb2wgPSBzYW1wbGVfaWQpLCBzaXplID0gMikKCmdncGxvdChkaWZmX2FidW5kYW5jZSwgYWVzKHggPSBjZWxsX3R5cGUsIHkgPSBwZXJjZW50YWdlX2NlbGxzLCBmaWxsID0gc2FtcGxlX3R5cGUpKSArCiAgZ2VvbV9ib3hwbG90KCkgKyAKICBsYWJzKHggPSAiQ2VsbCBUeXBlIiwgeSA9ICJQcm9wb3J0aW9uIG9mIGNlbGxzIChhdmVyYWdlIGFjcm9zcyBkb25vcnMpIiwgZmlsbCA9ICJTYW1wbGUgVHlwZSIsIGNvbCA9ICJTYW1wbGUgSUQiKSArCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLCBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDU1LCBoanVzdCA9IDEpLHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJ3aGl0ZSIsIGNvbG91ciA9ImRhcmtncmF5Iiwgc2l6ZSA9IDIpLCBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJncmF5Iiwgc2l6ZSA9IDAuMykpKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCIjRTc4QUMzIiwgIiNBMUQ5OUIiKSkrCiAgZ2VvbV9wb2ludChhZXMoY29sID0gc2FtcGxlX2lkKSwgc2l6ZSA9IDIpCgojK2dlb21fc2lnbmlmKHN0YXQgPSAiaWRlbnRpdHkiLCBkYXRhID0gZGF0YS5mcmFtZSh4ID0gYygwLjEyLCAwLjM3KSwgeGVuZCA9IGMoMC4xNywgKSwgeSA9IGMoMC40LCAwLjM5KSwgYW5ub3RhdGlvbiA9IGMoIioiLCAiKioiKSksIGFlcyh4ID0geCwgeGVuZCA9IHhlbmQsIHkgPSB5LCB5ZW5kID0geSwgYW5ub3RhdGlvbiA9IGFubm90YXRpb24pKQoKICAKYGBgCgoKYGBge3J9CmNkMTkubW9kZWwgPC0gbG0ocGVyY2VudGFnZV9jZWxscyB+IGNlbGxfdHlwZSArIHNhbXBsZV90eXBlLCBkYXRhID0gZGlmZl9hYnVuZGFuY2UpCnRlbXAgPC0gZGlmZl9hYnVuZGFuY2UgJT4lCiAgZ3JvdXBfYnkoY2VsbF90eXBlKSAlPiUKICBhbm92YV90ZXN0KHBlcmNlbnRhZ2VfY2VsbHMgfiBzYW1wbGVfdHlwZSwgZXJyb3IgPSBjZDE5Lm1vZGVsKQoKdGVtcAoKY2QxOS5tb2RlbCA8LSBsbShwZXJjZW50YWdlX2NlbGxzIH4gY2VsbF90eXBlKnNhbXBsZV90eXBlLCBkYXRhID0gZGlmZl9hYnVuZGFuY2UpCnRlbXAxIDwtIGRpZmZfYWJ1bmRhbmNlICU+JQogIGdyb3VwX2J5KGNlbGxfdHlwZSkgJT4lCiAgYW5vdmFfdGVzdChwZXJjZW50YWdlX2NlbGxzIH4gc2FtcGxlX3R5cGUsIGVycm9yID0gY2QxOS5tb2RlbCkKCnRlbXAxCgoKcHdjIDwtIGRpZmZfYWJ1bmRhbmNlICU+JSAKICBncm91cF9ieShjZWxsX3R5cGUpICU+JQogIGVtbWVhbnNfdGVzdChwZXJjZW50YWdlX2NlbGxzIH4gc2FtcGxlX3R5cGUsIHAuYWRqdXN0Lm1ldGhvZCA9ICJib25mZXJyb25pIikgCnB3YwogCnB3YzEgPC0gc3Vic2V0KHB3Yywgc2VsZWN0ID0gYyhjZWxsX3R5cGUsIHN0YXRpc3RpYywgcCkpCnB3YzEgPC0gcHdjMVtvcmRlcihwd2MxJHApLF0KY29sbmFtZXMocHdjMSkgPC0gYygiY2VsbF90eXBlIiwgInN0YXRpc3RpYyIsICJwX3ZhbHVlIikKcHdjMQpgYGAKCgpgYGB7cn0KCndob2xlX2RhIDwtIHdob2xlWyx3aG9sZSRjbHVzdGVyX25hbWUgJWluJSBjKCJGaWJyb2JsYXN0cyIsICJFbmRvdGhlbGlhbF9jZWxscyIsICJNeWVsb2lkX2NlbGxzIiwgIlBlcmljeXRlcyIpXQpzbGljZV9kYSA8LSBzbGljZVssc2xpY2UkY2x1c3Rlcl9uYW1lICVpbiUgYygiRmlicm9ibGFzdHMiLCAiRW5kb3RoZWxpYWxfY2VsbHMiLCAiTXllbG9pZF9jZWxscyIsICJQZXJpY3l0ZXMiKV0KCndob2xlX2RhIDwtIHdob2xlX2RhW3dob2xlX2RhJGRvbm9yX2lkICVpbiUgYygiUHJMTjQiLCAiUHJMTjUiLCAiUHJMTjYiKSwgXQpzbGljZV9kYSA8LSBzbGljZV9kYVtzbGljZV9kYSRzYW1wbGVfaWQgJWluJSBjKCJQckxONF9zQ1RSTCIsICJQckxONV9zQ1RSTCIsICJQckxONl9zQ1RSTCIpLF0KCgphc3NheXMoc2xpY2VfZGEpJGRlY29udFhjb3VudHMgPC0gTlVMTAoKY29tYmluZWQgPC0gYyh3aG9sZV9kYSwgc2xpY2VfZGEpCmBgYAoKCgoKCg==